Jelajahi Sumber

增加计费接口

boweniac 3 bulan lalu
induk
melakukan
f2ddc2a1cc
40 mengubah file dengan 12353 tambahan dan 7 penghapusan
  1. 3 1
      desc/all.api
  2. 80 0
      desc/wechat/usage_detail.api
  3. 65 0
      desc/wechat/usage_total.api
  4. 3 0
      desc/wechat/wx.api
  5. 290 6
      ent/client.go
  6. 4 0
      ent/ent.go
  7. 24 0
      ent/hook/hook.go
  8. 60 0
      ent/intercept/intercept.go
  9. 75 0
      ent/migrate/schema.go
  10. 2556 0
      ent/mutation.go
  11. 164 0
      ent/pagination.go
  12. 6 0
      ent/predicate/predicate.go
  13. 112 0
      ent/runtime/runtime.go
  14. 75 0
      ent/schema/usage_detail.go
  15. 60 0
      ent/schema/usage_total.go
  16. 504 0
      ent/set_not_nil.go
  17. 6 0
      ent/tx.go
  18. 249 0
      ent/usagedetail.go
  19. 186 0
      ent/usagedetail/usagedetail.go
  20. 880 0
      ent/usagedetail/where.go
  21. 1610 0
      ent/usagedetail_create.go
  22. 88 0
      ent/usagedetail_delete.go
  23. 526 0
      ent/usagedetail_query.go
  24. 924 0
      ent/usagedetail_update.go
  25. 194 0
      ent/usagetotal.go
  26. 136 0
      ent/usagetotal/usagetotal.go
  27. 560 0
      ent/usagetotal/where.go
  28. 1211 0
      ent/usagetotal_create.go
  29. 88 0
      ent/usagetotal_delete.go
  30. 526 0
      ent/usagetotal_query.go
  31. 678 0
      ent/usagetotal_update.go
  32. 35 0
      hook/contact.go
  33. 44 0
      internal/handler/UsageDetail/get_usage_detail_list_handler.go
  34. 44 0
      internal/handler/UsageTotal/get_usage_total_list_handler.go
  35. 30 0
      internal/handler/routes.go
  36. 74 0
      internal/logic/UsageDetail/get_usage_detail_list_logic.go
  37. 69 0
      internal/logic/UsageTotal/get_usage_total_list_logic.go
  38. 12 0
      internal/logic/Wx/get_wx_list_logic.go
  39. 2 0
      internal/logic/Wxhook/get_friends_and_groups_logic.go
  40. 100 0
      internal/types/types.go

+ 3 - 1
desc/all.api

@@ -30,4 +30,6 @@ import "./wechat/wx_card_user.api"
 import "./wechat/wx_card_visit.api"
 import "./wechat/avatar.api"
 import "./wechat/aliyun_avatar.api"
-import "./wechat/workphone.api"
+import "./wechat/workphone.api"
+import "./wechat/usage_detail.api"
+import "./wechat/usage_total.api"

+ 80 - 0
desc/wechat/usage_detail.api

@@ -0,0 +1,80 @@
+import "../base.api"
+
+type (
+    // The response data of UsageDetail information | UsageDetail信息
+    UsageDetailInfo {
+        BaseIDInfo
+
+        // Status 1: normal 2: ban | 状态 1 正常 2 禁用
+        Status  *uint8 `json:"status,optional"`
+
+        // 1 微信 2 名片
+        Type  *int `json:"type,optional"
+
+        // 微信id
+        BotId  *string `json:"botId,optional"`
+
+        // 微信id或open_id
+        ReceiverId  *string `json:"receiverId,optional"`
+
+        // 1 cow-basic 2 cow-agent 3 cow-sop 4 mp-card 5 mp-employee
+        App  *int `json:"app,optional"
+
+        // 名片会话id
+        SessionId *uint64 `json:"sessionId,optional"`
+
+        // 请求内容
+        Request  *string `json:"request,optional"`
+
+        // 响应内容
+        Response  *string `json:"response,optional"`
+
+        // 使用token总数
+        TotalTokens *uint64 `json:"totalTokens,optional"`
+
+        // 请求token数
+        PromptTokens *uint64 `json:"promptTokens,optional"`
+
+        // 响应token数
+        CompletionTokens *uint64 `json:"completionTokens,optional"`
+
+        // 组织ID
+        OrganizationId *uint64 `json:"organizationId,optional"`
+    }
+
+    // The response data of UsageDetail list | UsageDetail列表数据
+    UsageDetailListResp {
+        BaseDataInfo
+
+        // UsageDetail list data | UsageDetail列表数据
+        Data UsageDetailListInfo `json:"data"`
+    }
+
+    // UsageDetail list data | UsageDetail列表数据
+    UsageDetailListInfo {
+        BaseListInfo
+
+        // The API list data | UsageDetail列表数据
+        Data  []UsageDetailInfo  `json:"data"`
+    }
+
+    // Get wx list request params | Wx列表请求参数
+    UsageDetailListReq {
+        PageInfo
+
+        // 租户id
+        BotId  *string `json:"botId,optional"`
+    }
+)
+
+@server(
+    jwt: Auth
+    group: UsageDetail
+    middleware: Authority
+)
+
+service Wechat {
+    // Get usage detail list | 获取Wx列表
+    @handler getUsageDetailList
+    post /usage_detail/list (UsageDetailListReq) returns (UsageDetailListResp)
+}

+ 65 - 0
desc/wechat/usage_total.api

@@ -0,0 +1,65 @@
+import "../base.api"
+
+type (
+    // The response data of UsageTotal information | UsageTotal信息
+    UsageTotalInfo {
+        BaseIDInfo
+
+        // Status 1: normal 2: ban | 状态 1 正常 2 禁用
+        Status  *uint8 `json:"status,optional"`
+
+        // 1 微信 2 名片
+        Type  *int `json:"type,optional"
+
+        // 微信或名片id
+        BotId  *string `json:"botId,optional"`
+
+        // 使用token总数
+        TotalTokens *uint64 `json:"totalTokens,optional"`
+
+        // 重制后的起始usage_detail 索引
+        StartIndex *uint64 `json:"startIndex,optional"`
+
+        // usage_detail 索引
+        EndIndex *uint64 `json:"endIndex,optional"`
+
+        // 组织ID
+        OrganizationId *uint64 `json:"organizationId,optional"`
+    }
+
+    // The response data of UsageTotal list | UsageTotal列表数据
+    UsageTotalListResp {
+        BaseDataInfo
+
+        // UsageTotal list data | UsageTotal列表数据
+        Data UsageTotalListInfo `json:"data"`
+    }
+
+    // UsageTotal list data | UsageTotal列表数据
+    UsageTotalListInfo {
+        BaseListInfo
+
+        // The API list data | UsageTotal列表数据
+        Data  []UsageTotalInfo  `json:"data"`
+    }
+
+    // Get wx list request params | Wx列表请求参数
+    UsageTotalListReq {
+        PageInfo
+
+        // 租户id
+        OrganizationId  *uint64 `json:"organizationId,optional"`
+    }
+)
+
+@server(
+    jwt: Auth
+    group: UsageTotal
+    middleware: Authority
+)
+
+service Wechat {
+    // Get usage total list | 获取Wx列表
+    @handler getUsageTotalList
+    post /usage_total/list (UsageTotalListReq) returns (UsageTotalListResp)
+}

+ 3 - 0
desc/wechat/wx.api

@@ -69,6 +69,9 @@ type (
 
         // 群黑名单
         GroupBlockList []ContactInfo `json:"groupBlockList,optional"`
+
+        // 使用token总数
+        TotalTokens *uint64 `json:"totalTokens,optional"`
     }
 
     UpdateBlockAndAllowListReq {

+ 290 - 6
ent/client.go

@@ -32,6 +32,8 @@ import (
 	"wechat-api/ent/soptask"
 	"wechat-api/ent/token"
 	"wechat-api/ent/tutorial"
+	"wechat-api/ent/usagedetail"
+	"wechat-api/ent/usagetotal"
 	"wechat-api/ent/workexperience"
 	"wechat-api/ent/wx"
 	"wechat-api/ent/wxcard"
@@ -93,6 +95,10 @@ type Client struct {
 	Token *TokenClient
 	// Tutorial is the client for interacting with the Tutorial builders.
 	Tutorial *TutorialClient
+	// UsageDetail is the client for interacting with the UsageDetail builders.
+	UsageDetail *UsageDetailClient
+	// UsageTotal is the client for interacting with the UsageTotal builders.
+	UsageTotal *UsageTotalClient
 	// WorkExperience is the client for interacting with the WorkExperience builders.
 	WorkExperience *WorkExperienceClient
 	// Wx is the client for interacting with the Wx builders.
@@ -135,6 +141,8 @@ func (c *Client) init() {
 	c.SopTask = NewSopTaskClient(c.config)
 	c.Token = NewTokenClient(c.config)
 	c.Tutorial = NewTutorialClient(c.config)
+	c.UsageDetail = NewUsageDetailClient(c.config)
+	c.UsageTotal = NewUsageTotalClient(c.config)
 	c.WorkExperience = NewWorkExperienceClient(c.config)
 	c.Wx = NewWxClient(c.config)
 	c.WxCard = NewWxCardClient(c.config)
@@ -253,6 +261,8 @@ func (c *Client) Tx(ctx context.Context) (*Tx, error) {
 		SopTask:           NewSopTaskClient(cfg),
 		Token:             NewTokenClient(cfg),
 		Tutorial:          NewTutorialClient(cfg),
+		UsageDetail:       NewUsageDetailClient(cfg),
+		UsageTotal:        NewUsageTotalClient(cfg),
 		WorkExperience:    NewWorkExperienceClient(cfg),
 		Wx:                NewWxClient(cfg),
 		WxCard:            NewWxCardClient(cfg),
@@ -298,6 +308,8 @@ func (c *Client) BeginTx(ctx context.Context, opts *sql.TxOptions) (*Tx, error)
 		SopTask:           NewSopTaskClient(cfg),
 		Token:             NewTokenClient(cfg),
 		Tutorial:          NewTutorialClient(cfg),
+		UsageDetail:       NewUsageDetailClient(cfg),
+		UsageTotal:        NewUsageTotalClient(cfg),
 		WorkExperience:    NewWorkExperienceClient(cfg),
 		Wx:                NewWxClient(cfg),
 		WxCard:            NewWxCardClient(cfg),
@@ -335,8 +347,8 @@ func (c *Client) Use(hooks ...Hook) {
 		c.Agent, c.AgentBase, c.AliyunAvatar, c.BatchMsg, c.Category, c.ChatRecords,
 		c.ChatSession, 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.WxCard,
-		c.WxCardUser, c.WxCardVisit,
+		c.SopStage, c.SopTask, c.Token, c.Tutorial, c.UsageDetail, c.UsageTotal,
+		c.WorkExperience, c.Wx, c.WxCard, c.WxCardUser, c.WxCardVisit,
 	} {
 		n.Use(hooks...)
 	}
@@ -349,8 +361,8 @@ func (c *Client) Intercept(interceptors ...Interceptor) {
 		c.Agent, c.AgentBase, c.AliyunAvatar, c.BatchMsg, c.Category, c.ChatRecords,
 		c.ChatSession, 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.WxCard,
-		c.WxCardUser, c.WxCardVisit,
+		c.SopStage, c.SopTask, c.Token, c.Tutorial, c.UsageDetail, c.UsageTotal,
+		c.WorkExperience, c.Wx, c.WxCard, c.WxCardUser, c.WxCardVisit,
 	} {
 		n.Intercept(interceptors...)
 	}
@@ -401,6 +413,10 @@ func (c *Client) Mutate(ctx context.Context, m Mutation) (Value, error) {
 		return c.Token.mutate(ctx, m)
 	case *TutorialMutation:
 		return c.Tutorial.mutate(ctx, m)
+	case *UsageDetailMutation:
+		return c.UsageDetail.mutate(ctx, m)
+	case *UsageTotalMutation:
+		return c.UsageTotal.mutate(ctx, m)
 	case *WorkExperienceMutation:
 		return c.WorkExperience.mutate(ctx, m)
 	case *WxMutation:
@@ -3595,6 +3611,272 @@ func (c *TutorialClient) mutate(ctx context.Context, m *TutorialMutation) (Value
 	}
 }
 
+// UsageDetailClient is a client for the UsageDetail schema.
+type UsageDetailClient struct {
+	config
+}
+
+// NewUsageDetailClient returns a client for the UsageDetail from the given config.
+func NewUsageDetailClient(c config) *UsageDetailClient {
+	return &UsageDetailClient{config: c}
+}
+
+// Use adds a list of mutation hooks to the hooks stack.
+// A call to `Use(f, g, h)` equals to `usagedetail.Hooks(f(g(h())))`.
+func (c *UsageDetailClient) Use(hooks ...Hook) {
+	c.hooks.UsageDetail = append(c.hooks.UsageDetail, hooks...)
+}
+
+// Intercept adds a list of query interceptors to the interceptors stack.
+// A call to `Intercept(f, g, h)` equals to `usagedetail.Intercept(f(g(h())))`.
+func (c *UsageDetailClient) Intercept(interceptors ...Interceptor) {
+	c.inters.UsageDetail = append(c.inters.UsageDetail, interceptors...)
+}
+
+// Create returns a builder for creating a UsageDetail entity.
+func (c *UsageDetailClient) Create() *UsageDetailCreate {
+	mutation := newUsageDetailMutation(c.config, OpCreate)
+	return &UsageDetailCreate{config: c.config, hooks: c.Hooks(), mutation: mutation}
+}
+
+// CreateBulk returns a builder for creating a bulk of UsageDetail entities.
+func (c *UsageDetailClient) CreateBulk(builders ...*UsageDetailCreate) *UsageDetailCreateBulk {
+	return &UsageDetailCreateBulk{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 *UsageDetailClient) MapCreateBulk(slice any, setFunc func(*UsageDetailCreate, int)) *UsageDetailCreateBulk {
+	rv := reflect.ValueOf(slice)
+	if rv.Kind() != reflect.Slice {
+		return &UsageDetailCreateBulk{err: fmt.Errorf("calling to UsageDetailClient.MapCreateBulk with wrong type %T, need slice", slice)}
+	}
+	builders := make([]*UsageDetailCreate, rv.Len())
+	for i := 0; i < rv.Len(); i++ {
+		builders[i] = c.Create()
+		setFunc(builders[i], i)
+	}
+	return &UsageDetailCreateBulk{config: c.config, builders: builders}
+}
+
+// Update returns an update builder for UsageDetail.
+func (c *UsageDetailClient) Update() *UsageDetailUpdate {
+	mutation := newUsageDetailMutation(c.config, OpUpdate)
+	return &UsageDetailUpdate{config: c.config, hooks: c.Hooks(), mutation: mutation}
+}
+
+// UpdateOne returns an update builder for the given entity.
+func (c *UsageDetailClient) UpdateOne(ud *UsageDetail) *UsageDetailUpdateOne {
+	mutation := newUsageDetailMutation(c.config, OpUpdateOne, withUsageDetail(ud))
+	return &UsageDetailUpdateOne{config: c.config, hooks: c.Hooks(), mutation: mutation}
+}
+
+// UpdateOneID returns an update builder for the given id.
+func (c *UsageDetailClient) UpdateOneID(id uint64) *UsageDetailUpdateOne {
+	mutation := newUsageDetailMutation(c.config, OpUpdateOne, withUsageDetailID(id))
+	return &UsageDetailUpdateOne{config: c.config, hooks: c.Hooks(), mutation: mutation}
+}
+
+// Delete returns a delete builder for UsageDetail.
+func (c *UsageDetailClient) Delete() *UsageDetailDelete {
+	mutation := newUsageDetailMutation(c.config, OpDelete)
+	return &UsageDetailDelete{config: c.config, hooks: c.Hooks(), mutation: mutation}
+}
+
+// DeleteOne returns a builder for deleting the given entity.
+func (c *UsageDetailClient) DeleteOne(ud *UsageDetail) *UsageDetailDeleteOne {
+	return c.DeleteOneID(ud.ID)
+}
+
+// DeleteOneID returns a builder for deleting the given entity by its id.
+func (c *UsageDetailClient) DeleteOneID(id uint64) *UsageDetailDeleteOne {
+	builder := c.Delete().Where(usagedetail.ID(id))
+	builder.mutation.id = &id
+	builder.mutation.op = OpDeleteOne
+	return &UsageDetailDeleteOne{builder}
+}
+
+// Query returns a query builder for UsageDetail.
+func (c *UsageDetailClient) Query() *UsageDetailQuery {
+	return &UsageDetailQuery{
+		config: c.config,
+		ctx:    &QueryContext{Type: TypeUsageDetail},
+		inters: c.Interceptors(),
+	}
+}
+
+// Get returns a UsageDetail entity by its id.
+func (c *UsageDetailClient) Get(ctx context.Context, id uint64) (*UsageDetail, error) {
+	return c.Query().Where(usagedetail.ID(id)).Only(ctx)
+}
+
+// GetX is like Get, but panics if an error occurs.
+func (c *UsageDetailClient) GetX(ctx context.Context, id uint64) *UsageDetail {
+	obj, err := c.Get(ctx, id)
+	if err != nil {
+		panic(err)
+	}
+	return obj
+}
+
+// Hooks returns the client hooks.
+func (c *UsageDetailClient) Hooks() []Hook {
+	return c.hooks.UsageDetail
+}
+
+// Interceptors returns the client interceptors.
+func (c *UsageDetailClient) Interceptors() []Interceptor {
+	return c.inters.UsageDetail
+}
+
+func (c *UsageDetailClient) mutate(ctx context.Context, m *UsageDetailMutation) (Value, error) {
+	switch m.Op() {
+	case OpCreate:
+		return (&UsageDetailCreate{config: c.config, hooks: c.Hooks(), mutation: m}).Save(ctx)
+	case OpUpdate:
+		return (&UsageDetailUpdate{config: c.config, hooks: c.Hooks(), mutation: m}).Save(ctx)
+	case OpUpdateOne:
+		return (&UsageDetailUpdateOne{config: c.config, hooks: c.Hooks(), mutation: m}).Save(ctx)
+	case OpDelete, OpDeleteOne:
+		return (&UsageDetailDelete{config: c.config, hooks: c.Hooks(), mutation: m}).Exec(ctx)
+	default:
+		return nil, fmt.Errorf("ent: unknown UsageDetail mutation op: %q", m.Op())
+	}
+}
+
+// UsageTotalClient is a client for the UsageTotal schema.
+type UsageTotalClient struct {
+	config
+}
+
+// NewUsageTotalClient returns a client for the UsageTotal from the given config.
+func NewUsageTotalClient(c config) *UsageTotalClient {
+	return &UsageTotalClient{config: c}
+}
+
+// Use adds a list of mutation hooks to the hooks stack.
+// A call to `Use(f, g, h)` equals to `usagetotal.Hooks(f(g(h())))`.
+func (c *UsageTotalClient) Use(hooks ...Hook) {
+	c.hooks.UsageTotal = append(c.hooks.UsageTotal, hooks...)
+}
+
+// Intercept adds a list of query interceptors to the interceptors stack.
+// A call to `Intercept(f, g, h)` equals to `usagetotal.Intercept(f(g(h())))`.
+func (c *UsageTotalClient) Intercept(interceptors ...Interceptor) {
+	c.inters.UsageTotal = append(c.inters.UsageTotal, interceptors...)
+}
+
+// Create returns a builder for creating a UsageTotal entity.
+func (c *UsageTotalClient) Create() *UsageTotalCreate {
+	mutation := newUsageTotalMutation(c.config, OpCreate)
+	return &UsageTotalCreate{config: c.config, hooks: c.Hooks(), mutation: mutation}
+}
+
+// CreateBulk returns a builder for creating a bulk of UsageTotal entities.
+func (c *UsageTotalClient) CreateBulk(builders ...*UsageTotalCreate) *UsageTotalCreateBulk {
+	return &UsageTotalCreateBulk{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 *UsageTotalClient) MapCreateBulk(slice any, setFunc func(*UsageTotalCreate, int)) *UsageTotalCreateBulk {
+	rv := reflect.ValueOf(slice)
+	if rv.Kind() != reflect.Slice {
+		return &UsageTotalCreateBulk{err: fmt.Errorf("calling to UsageTotalClient.MapCreateBulk with wrong type %T, need slice", slice)}
+	}
+	builders := make([]*UsageTotalCreate, rv.Len())
+	for i := 0; i < rv.Len(); i++ {
+		builders[i] = c.Create()
+		setFunc(builders[i], i)
+	}
+	return &UsageTotalCreateBulk{config: c.config, builders: builders}
+}
+
+// Update returns an update builder for UsageTotal.
+func (c *UsageTotalClient) Update() *UsageTotalUpdate {
+	mutation := newUsageTotalMutation(c.config, OpUpdate)
+	return &UsageTotalUpdate{config: c.config, hooks: c.Hooks(), mutation: mutation}
+}
+
+// UpdateOne returns an update builder for the given entity.
+func (c *UsageTotalClient) UpdateOne(ut *UsageTotal) *UsageTotalUpdateOne {
+	mutation := newUsageTotalMutation(c.config, OpUpdateOne, withUsageTotal(ut))
+	return &UsageTotalUpdateOne{config: c.config, hooks: c.Hooks(), mutation: mutation}
+}
+
+// UpdateOneID returns an update builder for the given id.
+func (c *UsageTotalClient) UpdateOneID(id uint64) *UsageTotalUpdateOne {
+	mutation := newUsageTotalMutation(c.config, OpUpdateOne, withUsageTotalID(id))
+	return &UsageTotalUpdateOne{config: c.config, hooks: c.Hooks(), mutation: mutation}
+}
+
+// Delete returns a delete builder for UsageTotal.
+func (c *UsageTotalClient) Delete() *UsageTotalDelete {
+	mutation := newUsageTotalMutation(c.config, OpDelete)
+	return &UsageTotalDelete{config: c.config, hooks: c.Hooks(), mutation: mutation}
+}
+
+// DeleteOne returns a builder for deleting the given entity.
+func (c *UsageTotalClient) DeleteOne(ut *UsageTotal) *UsageTotalDeleteOne {
+	return c.DeleteOneID(ut.ID)
+}
+
+// DeleteOneID returns a builder for deleting the given entity by its id.
+func (c *UsageTotalClient) DeleteOneID(id uint64) *UsageTotalDeleteOne {
+	builder := c.Delete().Where(usagetotal.ID(id))
+	builder.mutation.id = &id
+	builder.mutation.op = OpDeleteOne
+	return &UsageTotalDeleteOne{builder}
+}
+
+// Query returns a query builder for UsageTotal.
+func (c *UsageTotalClient) Query() *UsageTotalQuery {
+	return &UsageTotalQuery{
+		config: c.config,
+		ctx:    &QueryContext{Type: TypeUsageTotal},
+		inters: c.Interceptors(),
+	}
+}
+
+// Get returns a UsageTotal entity by its id.
+func (c *UsageTotalClient) Get(ctx context.Context, id uint64) (*UsageTotal, error) {
+	return c.Query().Where(usagetotal.ID(id)).Only(ctx)
+}
+
+// GetX is like Get, but panics if an error occurs.
+func (c *UsageTotalClient) GetX(ctx context.Context, id uint64) *UsageTotal {
+	obj, err := c.Get(ctx, id)
+	if err != nil {
+		panic(err)
+	}
+	return obj
+}
+
+// Hooks returns the client hooks.
+func (c *UsageTotalClient) Hooks() []Hook {
+	return c.hooks.UsageTotal
+}
+
+// Interceptors returns the client interceptors.
+func (c *UsageTotalClient) Interceptors() []Interceptor {
+	return c.inters.UsageTotal
+}
+
+func (c *UsageTotalClient) mutate(ctx context.Context, m *UsageTotalMutation) (Value, error) {
+	switch m.Op() {
+	case OpCreate:
+		return (&UsageTotalCreate{config: c.config, hooks: c.Hooks(), mutation: m}).Save(ctx)
+	case OpUpdate:
+		return (&UsageTotalUpdate{config: c.config, hooks: c.Hooks(), mutation: m}).Save(ctx)
+	case OpUpdateOne:
+		return (&UsageTotalUpdateOne{config: c.config, hooks: c.Hooks(), mutation: m}).Save(ctx)
+	case OpDelete, OpDeleteOne:
+		return (&UsageTotalDelete{config: c.config, hooks: c.Hooks(), mutation: m}).Exec(ctx)
+	default:
+		return nil, fmt.Errorf("ent: unknown UsageTotal mutation op: %q", m.Op())
+	}
+}
+
 // WorkExperienceClient is a client for the WorkExperience schema.
 type WorkExperienceClient struct {
 	config
@@ -4324,13 +4606,15 @@ type (
 		Agent, AgentBase, AliyunAvatar, BatchMsg, Category, ChatRecords, ChatSession,
 		Contact, Employee, EmployeeConfig, Label, LabelRelationship, Message,
 		MessageRecords, Msg, Server, SopNode, SopStage, SopTask, Token, Tutorial,
-		WorkExperience, Wx, WxCard, WxCardUser, WxCardVisit []ent.Hook
+		UsageDetail, UsageTotal, WorkExperience, Wx, WxCard, WxCardUser,
+		WxCardVisit []ent.Hook
 	}
 	inters struct {
 		Agent, AgentBase, AliyunAvatar, BatchMsg, Category, ChatRecords, ChatSession,
 		Contact, Employee, EmployeeConfig, Label, LabelRelationship, Message,
 		MessageRecords, Msg, Server, SopNode, SopStage, SopTask, Token, Tutorial,
-		WorkExperience, Wx, WxCard, WxCardUser, WxCardVisit []ent.Interceptor
+		UsageDetail, UsageTotal, WorkExperience, Wx, WxCard, WxCardUser,
+		WxCardVisit []ent.Interceptor
 	}
 )
 

+ 4 - 0
ent/ent.go

@@ -29,6 +29,8 @@ import (
 	"wechat-api/ent/soptask"
 	"wechat-api/ent/token"
 	"wechat-api/ent/tutorial"
+	"wechat-api/ent/usagedetail"
+	"wechat-api/ent/usagetotal"
 	"wechat-api/ent/workexperience"
 	"wechat-api/ent/wx"
 	"wechat-api/ent/wxcard"
@@ -119,6 +121,8 @@ func checkColumn(table, column string) error {
 			soptask.Table:           soptask.ValidColumn,
 			token.Table:             token.ValidColumn,
 			tutorial.Table:          tutorial.ValidColumn,
+			usagedetail.Table:       usagedetail.ValidColumn,
+			usagetotal.Table:        usagetotal.ValidColumn,
 			workexperience.Table:    workexperience.ValidColumn,
 			wx.Table:                wx.ValidColumn,
 			wxcard.Table:            wxcard.ValidColumn,

+ 24 - 0
ent/hook/hook.go

@@ -260,6 +260,30 @@ func (f TutorialFunc) Mutate(ctx context.Context, m ent.Mutation) (ent.Value, er
 	return nil, fmt.Errorf("unexpected mutation type %T. expect *ent.TutorialMutation", m)
 }
 
+// The UsageDetailFunc type is an adapter to allow the use of ordinary
+// function as UsageDetail mutator.
+type UsageDetailFunc func(context.Context, *ent.UsageDetailMutation) (ent.Value, error)
+
+// Mutate calls f(ctx, m).
+func (f UsageDetailFunc) Mutate(ctx context.Context, m ent.Mutation) (ent.Value, error) {
+	if mv, ok := m.(*ent.UsageDetailMutation); ok {
+		return f(ctx, mv)
+	}
+	return nil, fmt.Errorf("unexpected mutation type %T. expect *ent.UsageDetailMutation", m)
+}
+
+// The UsageTotalFunc type is an adapter to allow the use of ordinary
+// function as UsageTotal mutator.
+type UsageTotalFunc func(context.Context, *ent.UsageTotalMutation) (ent.Value, error)
+
+// Mutate calls f(ctx, m).
+func (f UsageTotalFunc) Mutate(ctx context.Context, m ent.Mutation) (ent.Value, error) {
+	if mv, ok := m.(*ent.UsageTotalMutation); ok {
+		return f(ctx, mv)
+	}
+	return nil, fmt.Errorf("unexpected mutation type %T. expect *ent.UsageTotalMutation", m)
+}
+
 // The WorkExperienceFunc type is an adapter to allow the use of ordinary
 // function as WorkExperience mutator.
 type WorkExperienceFunc func(context.Context, *ent.WorkExperienceMutation) (ent.Value, error)

+ 60 - 0
ent/intercept/intercept.go

@@ -28,6 +28,8 @@ import (
 	"wechat-api/ent/soptask"
 	"wechat-api/ent/token"
 	"wechat-api/ent/tutorial"
+	"wechat-api/ent/usagedetail"
+	"wechat-api/ent/usagetotal"
 	"wechat-api/ent/workexperience"
 	"wechat-api/ent/wx"
 	"wechat-api/ent/wxcard"
@@ -660,6 +662,60 @@ func (f TraverseTutorial) Traverse(ctx context.Context, q ent.Query) error {
 	return fmt.Errorf("unexpected query type %T. expect *ent.TutorialQuery", q)
 }
 
+// The UsageDetailFunc type is an adapter to allow the use of ordinary function as a Querier.
+type UsageDetailFunc func(context.Context, *ent.UsageDetailQuery) (ent.Value, error)
+
+// Query calls f(ctx, q).
+func (f UsageDetailFunc) Query(ctx context.Context, q ent.Query) (ent.Value, error) {
+	if q, ok := q.(*ent.UsageDetailQuery); ok {
+		return f(ctx, q)
+	}
+	return nil, fmt.Errorf("unexpected query type %T. expect *ent.UsageDetailQuery", q)
+}
+
+// The TraverseUsageDetail type is an adapter to allow the use of ordinary function as Traverser.
+type TraverseUsageDetail func(context.Context, *ent.UsageDetailQuery) error
+
+// Intercept is a dummy implementation of Intercept that returns the next Querier in the pipeline.
+func (f TraverseUsageDetail) Intercept(next ent.Querier) ent.Querier {
+	return next
+}
+
+// Traverse calls f(ctx, q).
+func (f TraverseUsageDetail) Traverse(ctx context.Context, q ent.Query) error {
+	if q, ok := q.(*ent.UsageDetailQuery); ok {
+		return f(ctx, q)
+	}
+	return fmt.Errorf("unexpected query type %T. expect *ent.UsageDetailQuery", q)
+}
+
+// The UsageTotalFunc type is an adapter to allow the use of ordinary function as a Querier.
+type UsageTotalFunc func(context.Context, *ent.UsageTotalQuery) (ent.Value, error)
+
+// Query calls f(ctx, q).
+func (f UsageTotalFunc) Query(ctx context.Context, q ent.Query) (ent.Value, error) {
+	if q, ok := q.(*ent.UsageTotalQuery); ok {
+		return f(ctx, q)
+	}
+	return nil, fmt.Errorf("unexpected query type %T. expect *ent.UsageTotalQuery", q)
+}
+
+// The TraverseUsageTotal type is an adapter to allow the use of ordinary function as Traverser.
+type TraverseUsageTotal func(context.Context, *ent.UsageTotalQuery) error
+
+// Intercept is a dummy implementation of Intercept that returns the next Querier in the pipeline.
+func (f TraverseUsageTotal) Intercept(next ent.Querier) ent.Querier {
+	return next
+}
+
+// Traverse calls f(ctx, q).
+func (f TraverseUsageTotal) Traverse(ctx context.Context, q ent.Query) error {
+	if q, ok := q.(*ent.UsageTotalQuery); ok {
+		return f(ctx, q)
+	}
+	return fmt.Errorf("unexpected query type %T. expect *ent.UsageTotalQuery", q)
+}
+
 // The WorkExperienceFunc type is an adapter to allow the use of ordinary function as a Querier.
 type WorkExperienceFunc func(context.Context, *ent.WorkExperienceQuery) (ent.Value, error)
 
@@ -840,6 +896,10 @@ func NewQuery(q ent.Query) (Query, error) {
 		return &query[*ent.TokenQuery, predicate.Token, token.OrderOption]{typ: ent.TypeToken, tq: q}, nil
 	case *ent.TutorialQuery:
 		return &query[*ent.TutorialQuery, predicate.Tutorial, tutorial.OrderOption]{typ: ent.TypeTutorial, tq: q}, nil
+	case *ent.UsageDetailQuery:
+		return &query[*ent.UsageDetailQuery, predicate.UsageDetail, usagedetail.OrderOption]{typ: ent.TypeUsageDetail, tq: q}, nil
+	case *ent.UsageTotalQuery:
+		return &query[*ent.UsageTotalQuery, predicate.UsageTotal, usagetotal.OrderOption]{typ: ent.TypeUsageTotal, tq: q}, nil
 	case *ent.WorkExperienceQuery:
 		return &query[*ent.WorkExperienceQuery, predicate.WorkExperience, workexperience.OrderOption]{typ: ent.TypeWorkExperience, tq: q}, nil
 	case *ent.WxQuery:

+ 75 - 0
ent/migrate/schema.go

@@ -707,6 +707,73 @@ var (
 			},
 		},
 	}
+	// UsageDetailColumns holds the columns for the "usage_detail" table.
+	UsageDetailColumns = []*schema.Column{
+		{Name: "id", Type: field.TypeUint64, Increment: true},
+		{Name: "created_at", Type: field.TypeTime, Comment: "Create Time | 创建日期"},
+		{Name: "updated_at", Type: field.TypeTime, Comment: "Update Time | 修改日期"},
+		{Name: "status", Type: field.TypeUint8, Nullable: true, Comment: "Status 1: normal 2: ban | 状态 1 正常 2 禁用", Default: 1},
+		{Name: "type", Type: field.TypeInt, Nullable: true, Comment: "1 微信 2 名片", Default: 1},
+		{Name: "bot_id", Type: field.TypeString, Comment: "微信或名片id", Default: ""},
+		{Name: "receiver_id", Type: field.TypeString, Comment: "微信id或open_id", Default: ""},
+		{Name: "app", Type: field.TypeInt, Nullable: true, Comment: "1 cow-basic 2 cow-agent 3 cow-sop 4 mp-card 5 mp-employee", Default: 1},
+		{Name: "session_id", Type: field.TypeUint64, Nullable: true, Comment: "名片会话id", Default: 1},
+		{Name: "request", Type: field.TypeString, Comment: "请求内容", Default: ""},
+		{Name: "response", Type: field.TypeString, Comment: "响应内容", Default: ""},
+		{Name: "total_tokens", Type: field.TypeUint64, Nullable: true, Comment: "使用token总数", Default: 0},
+		{Name: "prompt_tokens", Type: field.TypeUint64, Nullable: true, Comment: "请求token数", Default: 0},
+		{Name: "completion_tokens", Type: field.TypeUint64, Nullable: true, Comment: "响应token数", Default: 0},
+		{Name: "organization_id", Type: field.TypeUint64, Nullable: true, Comment: "机构 ID", Default: 1},
+	}
+	// UsageDetailTable holds the schema information for the "usage_detail" table.
+	UsageDetailTable = &schema.Table{
+		Name:       "usage_detail",
+		Columns:    UsageDetailColumns,
+		PrimaryKey: []*schema.Column{UsageDetailColumns[0]},
+		Indexes: []*schema.Index{
+			{
+				Name:    "usagedetail_bot_id",
+				Unique:  false,
+				Columns: []*schema.Column{UsageDetailColumns[5]},
+			},
+			{
+				Name:    "usagedetail_organization_id",
+				Unique:  false,
+				Columns: []*schema.Column{UsageDetailColumns[14]},
+			},
+		},
+	}
+	// UsageTotalColumns holds the columns for the "usage_total" table.
+	UsageTotalColumns = []*schema.Column{
+		{Name: "id", Type: field.TypeUint64, Increment: true},
+		{Name: "created_at", Type: field.TypeTime, Comment: "Create Time | 创建日期"},
+		{Name: "updated_at", Type: field.TypeTime, Comment: "Update Time | 修改日期"},
+		{Name: "status", Type: field.TypeUint8, Nullable: true, Comment: "Status 1: normal 2: ban | 状态 1 正常 2 禁用", Default: 1},
+		{Name: "type", Type: field.TypeInt, Nullable: true, Comment: "1 微信 2 名片", Default: 1},
+		{Name: "bot_id", Type: field.TypeString, Comment: "微信或名片id", Default: ""},
+		{Name: "total_tokens", Type: field.TypeUint64, Nullable: true, Comment: "使用token总数", Default: 0},
+		{Name: "start_index", Type: field.TypeUint64, Nullable: true, Comment: "重制后的起始usage_detail 索引", Default: 0},
+		{Name: "end_index", Type: field.TypeUint64, Nullable: true, Comment: "usage_detail 索引", Default: 0},
+		{Name: "organization_id", Type: field.TypeUint64, Nullable: true, Comment: "机构 ID", Default: 1},
+	}
+	// UsageTotalTable holds the schema information for the "usage_total" table.
+	UsageTotalTable = &schema.Table{
+		Name:       "usage_total",
+		Columns:    UsageTotalColumns,
+		PrimaryKey: []*schema.Column{UsageTotalColumns[0]},
+		Indexes: []*schema.Index{
+			{
+				Name:    "usagetotal_bot_id",
+				Unique:  false,
+				Columns: []*schema.Column{UsageTotalColumns[5]},
+			},
+			{
+				Name:    "usagetotal_organization_id",
+				Unique:  false,
+				Columns: []*schema.Column{UsageTotalColumns[9]},
+			},
+		},
+	}
 	// WorkExperienceColumns holds the columns for the "work_experience" table.
 	WorkExperienceColumns = []*schema.Column{
 		{Name: "id", Type: field.TypeUint64, Increment: true},
@@ -941,6 +1008,8 @@ var (
 		SopTaskTable,
 		TokenTable,
 		TutorialTable,
+		UsageDetailTable,
+		UsageTotalTable,
 		WorkExperienceTable,
 		WxTable,
 		WxCardTable,
@@ -1022,6 +1091,12 @@ func init() {
 	TutorialTable.Annotation = &entsql.Annotation{
 		Table: "tutorial",
 	}
+	UsageDetailTable.Annotation = &entsql.Annotation{
+		Table: "usage_detail",
+	}
+	UsageTotalTable.Annotation = &entsql.Annotation{
+		Table: "usage_total",
+	}
 	WorkExperienceTable.ForeignKeys[0].RefTable = EmployeeTable
 	WorkExperienceTable.Annotation = &entsql.Annotation{
 		Table: "work_experience",

+ 2556 - 0
ent/mutation.go

@@ -31,6 +31,8 @@ import (
 	"wechat-api/ent/soptask"
 	"wechat-api/ent/token"
 	"wechat-api/ent/tutorial"
+	"wechat-api/ent/usagedetail"
+	"wechat-api/ent/usagetotal"
 	"wechat-api/ent/workexperience"
 	"wechat-api/ent/wx"
 	"wechat-api/ent/wxcard"
@@ -71,6 +73,8 @@ const (
 	TypeSopTask           = "SopTask"
 	TypeToken             = "Token"
 	TypeTutorial          = "Tutorial"
+	TypeUsageDetail       = "UsageDetail"
+	TypeUsageTotal        = "UsageTotal"
 	TypeWorkExperience    = "WorkExperience"
 	TypeWx                = "Wx"
 	TypeWxCard            = "WxCard"
@@ -24451,6 +24455,2558 @@ func (m *TutorialMutation) ResetEdge(name string) error {
 	return fmt.Errorf("unknown Tutorial edge %s", name)
 }
 
+// UsageDetailMutation represents an operation that mutates the UsageDetail nodes in the graph.
+type UsageDetailMutation struct {
+	config
+	op                   Op
+	typ                  string
+	id                   *uint64
+	created_at           *time.Time
+	updated_at           *time.Time
+	status               *uint8
+	addstatus            *int8
+	_type                *int
+	add_type             *int
+	bot_id               *string
+	receiver_id          *string
+	app                  *int
+	addapp               *int
+	session_id           *uint64
+	addsession_id        *int64
+	request              *string
+	response             *string
+	total_tokens         *uint64
+	addtotal_tokens      *int64
+	prompt_tokens        *uint64
+	addprompt_tokens     *int64
+	completion_tokens    *uint64
+	addcompletion_tokens *int64
+	organization_id      *uint64
+	addorganization_id   *int64
+	clearedFields        map[string]struct{}
+	done                 bool
+	oldValue             func(context.Context) (*UsageDetail, error)
+	predicates           []predicate.UsageDetail
+}
+
+var _ ent.Mutation = (*UsageDetailMutation)(nil)
+
+// usagedetailOption allows management of the mutation configuration using functional options.
+type usagedetailOption func(*UsageDetailMutation)
+
+// newUsageDetailMutation creates new mutation for the UsageDetail entity.
+func newUsageDetailMutation(c config, op Op, opts ...usagedetailOption) *UsageDetailMutation {
+	m := &UsageDetailMutation{
+		config:        c,
+		op:            op,
+		typ:           TypeUsageDetail,
+		clearedFields: make(map[string]struct{}),
+	}
+	for _, opt := range opts {
+		opt(m)
+	}
+	return m
+}
+
+// withUsageDetailID sets the ID field of the mutation.
+func withUsageDetailID(id uint64) usagedetailOption {
+	return func(m *UsageDetailMutation) {
+		var (
+			err   error
+			once  sync.Once
+			value *UsageDetail
+		)
+		m.oldValue = func(ctx context.Context) (*UsageDetail, error) {
+			once.Do(func() {
+				if m.done {
+					err = errors.New("querying old values post mutation is not allowed")
+				} else {
+					value, err = m.Client().UsageDetail.Get(ctx, id)
+				}
+			})
+			return value, err
+		}
+		m.id = &id
+	}
+}
+
+// withUsageDetail sets the old UsageDetail of the mutation.
+func withUsageDetail(node *UsageDetail) usagedetailOption {
+	return func(m *UsageDetailMutation) {
+		m.oldValue = func(context.Context) (*UsageDetail, 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 UsageDetailMutation) 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 UsageDetailMutation) 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 UsageDetail entities.
+func (m *UsageDetailMutation) SetID(id uint64) {
+	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 *UsageDetailMutation) ID() (id uint64, 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 *UsageDetailMutation) IDs(ctx context.Context) ([]uint64, error) {
+	switch {
+	case m.op.Is(OpUpdateOne | OpDeleteOne):
+		id, exists := m.ID()
+		if exists {
+			return []uint64{id}, nil
+		}
+		fallthrough
+	case m.op.Is(OpUpdate | OpDelete):
+		return m.Client().UsageDetail.Query().Where(m.predicates...).IDs(ctx)
+	default:
+		return nil, fmt.Errorf("IDs is not allowed on %s operations", m.op)
+	}
+}
+
+// SetCreatedAt sets the "created_at" field.
+func (m *UsageDetailMutation) SetCreatedAt(t time.Time) {
+	m.created_at = &t
+}
+
+// CreatedAt returns the value of the "created_at" field in the mutation.
+func (m *UsageDetailMutation) CreatedAt() (r time.Time, exists bool) {
+	v := m.created_at
+	if v == nil {
+		return
+	}
+	return *v, true
+}
+
+// OldCreatedAt returns the old "created_at" field's value of the UsageDetail entity.
+// If the UsageDetail 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 *UsageDetailMutation) OldCreatedAt(ctx context.Context) (v time.Time, err error) {
+	if !m.op.Is(OpUpdateOne) {
+		return v, errors.New("OldCreatedAt is only allowed on UpdateOne operations")
+	}
+	if m.id == nil || m.oldValue == nil {
+		return v, errors.New("OldCreatedAt requires an ID field in the mutation")
+	}
+	oldValue, err := m.oldValue(ctx)
+	if err != nil {
+		return v, fmt.Errorf("querying old value for OldCreatedAt: %w", err)
+	}
+	return oldValue.CreatedAt, nil
+}
+
+// ResetCreatedAt resets all changes to the "created_at" field.
+func (m *UsageDetailMutation) ResetCreatedAt() {
+	m.created_at = nil
+}
+
+// SetUpdatedAt sets the "updated_at" field.
+func (m *UsageDetailMutation) SetUpdatedAt(t time.Time) {
+	m.updated_at = &t
+}
+
+// UpdatedAt returns the value of the "updated_at" field in the mutation.
+func (m *UsageDetailMutation) UpdatedAt() (r time.Time, exists bool) {
+	v := m.updated_at
+	if v == nil {
+		return
+	}
+	return *v, true
+}
+
+// OldUpdatedAt returns the old "updated_at" field's value of the UsageDetail entity.
+// If the UsageDetail 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 *UsageDetailMutation) OldUpdatedAt(ctx context.Context) (v time.Time, err error) {
+	if !m.op.Is(OpUpdateOne) {
+		return v, errors.New("OldUpdatedAt is only allowed on UpdateOne operations")
+	}
+	if m.id == nil || m.oldValue == nil {
+		return v, errors.New("OldUpdatedAt requires an ID field in the mutation")
+	}
+	oldValue, err := m.oldValue(ctx)
+	if err != nil {
+		return v, fmt.Errorf("querying old value for OldUpdatedAt: %w", err)
+	}
+	return oldValue.UpdatedAt, nil
+}
+
+// ResetUpdatedAt resets all changes to the "updated_at" field.
+func (m *UsageDetailMutation) ResetUpdatedAt() {
+	m.updated_at = nil
+}
+
+// SetStatus sets the "status" field.
+func (m *UsageDetailMutation) SetStatus(u uint8) {
+	m.status = &u
+	m.addstatus = nil
+}
+
+// Status returns the value of the "status" field in the mutation.
+func (m *UsageDetailMutation) Status() (r uint8, exists bool) {
+	v := m.status
+	if v == nil {
+		return
+	}
+	return *v, true
+}
+
+// OldStatus returns the old "status" field's value of the UsageDetail entity.
+// If the UsageDetail 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 *UsageDetailMutation) OldStatus(ctx context.Context) (v uint8, err error) {
+	if !m.op.Is(OpUpdateOne) {
+		return v, errors.New("OldStatus is only allowed on UpdateOne operations")
+	}
+	if m.id == nil || m.oldValue == nil {
+		return v, errors.New("OldStatus requires an ID field in the mutation")
+	}
+	oldValue, err := m.oldValue(ctx)
+	if err != nil {
+		return v, fmt.Errorf("querying old value for OldStatus: %w", err)
+	}
+	return oldValue.Status, nil
+}
+
+// AddStatus adds u to the "status" field.
+func (m *UsageDetailMutation) AddStatus(u int8) {
+	if m.addstatus != nil {
+		*m.addstatus += u
+	} else {
+		m.addstatus = &u
+	}
+}
+
+// AddedStatus returns the value that was added to the "status" field in this mutation.
+func (m *UsageDetailMutation) AddedStatus() (r int8, exists bool) {
+	v := m.addstatus
+	if v == nil {
+		return
+	}
+	return *v, true
+}
+
+// ClearStatus clears the value of the "status" field.
+func (m *UsageDetailMutation) ClearStatus() {
+	m.status = nil
+	m.addstatus = nil
+	m.clearedFields[usagedetail.FieldStatus] = struct{}{}
+}
+
+// StatusCleared returns if the "status" field was cleared in this mutation.
+func (m *UsageDetailMutation) StatusCleared() bool {
+	_, ok := m.clearedFields[usagedetail.FieldStatus]
+	return ok
+}
+
+// ResetStatus resets all changes to the "status" field.
+func (m *UsageDetailMutation) ResetStatus() {
+	m.status = nil
+	m.addstatus = nil
+	delete(m.clearedFields, usagedetail.FieldStatus)
+}
+
+// SetType sets the "type" field.
+func (m *UsageDetailMutation) SetType(i int) {
+	m._type = &i
+	m.add_type = nil
+}
+
+// GetType returns the value of the "type" field in the mutation.
+func (m *UsageDetailMutation) GetType() (r int, exists bool) {
+	v := m._type
+	if v == nil {
+		return
+	}
+	return *v, true
+}
+
+// OldType returns the old "type" field's value of the UsageDetail entity.
+// If the UsageDetail 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 *UsageDetailMutation) OldType(ctx context.Context) (v int, err error) {
+	if !m.op.Is(OpUpdateOne) {
+		return v, errors.New("OldType is only allowed on UpdateOne operations")
+	}
+	if m.id == nil || m.oldValue == nil {
+		return v, errors.New("OldType requires an ID field in the mutation")
+	}
+	oldValue, err := m.oldValue(ctx)
+	if err != nil {
+		return v, fmt.Errorf("querying old value for OldType: %w", err)
+	}
+	return oldValue.Type, nil
+}
+
+// AddType adds i to the "type" field.
+func (m *UsageDetailMutation) AddType(i int) {
+	if m.add_type != nil {
+		*m.add_type += i
+	} else {
+		m.add_type = &i
+	}
+}
+
+// AddedType returns the value that was added to the "type" field in this mutation.
+func (m *UsageDetailMutation) AddedType() (r int, exists bool) {
+	v := m.add_type
+	if v == nil {
+		return
+	}
+	return *v, true
+}
+
+// ClearType clears the value of the "type" field.
+func (m *UsageDetailMutation) ClearType() {
+	m._type = nil
+	m.add_type = nil
+	m.clearedFields[usagedetail.FieldType] = struct{}{}
+}
+
+// TypeCleared returns if the "type" field was cleared in this mutation.
+func (m *UsageDetailMutation) TypeCleared() bool {
+	_, ok := m.clearedFields[usagedetail.FieldType]
+	return ok
+}
+
+// ResetType resets all changes to the "type" field.
+func (m *UsageDetailMutation) ResetType() {
+	m._type = nil
+	m.add_type = nil
+	delete(m.clearedFields, usagedetail.FieldType)
+}
+
+// SetBotID sets the "bot_id" field.
+func (m *UsageDetailMutation) SetBotID(s string) {
+	m.bot_id = &s
+}
+
+// BotID returns the value of the "bot_id" field in the mutation.
+func (m *UsageDetailMutation) BotID() (r string, exists bool) {
+	v := m.bot_id
+	if v == nil {
+		return
+	}
+	return *v, true
+}
+
+// OldBotID returns the old "bot_id" field's value of the UsageDetail entity.
+// If the UsageDetail 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 *UsageDetailMutation) OldBotID(ctx context.Context) (v string, err error) {
+	if !m.op.Is(OpUpdateOne) {
+		return v, errors.New("OldBotID is only allowed on UpdateOne operations")
+	}
+	if m.id == nil || m.oldValue == nil {
+		return v, errors.New("OldBotID requires an ID field in the mutation")
+	}
+	oldValue, err := m.oldValue(ctx)
+	if err != nil {
+		return v, fmt.Errorf("querying old value for OldBotID: %w", err)
+	}
+	return oldValue.BotID, nil
+}
+
+// ResetBotID resets all changes to the "bot_id" field.
+func (m *UsageDetailMutation) ResetBotID() {
+	m.bot_id = nil
+}
+
+// SetReceiverID sets the "receiver_id" field.
+func (m *UsageDetailMutation) SetReceiverID(s string) {
+	m.receiver_id = &s
+}
+
+// ReceiverID returns the value of the "receiver_id" field in the mutation.
+func (m *UsageDetailMutation) ReceiverID() (r string, exists bool) {
+	v := m.receiver_id
+	if v == nil {
+		return
+	}
+	return *v, true
+}
+
+// OldReceiverID returns the old "receiver_id" field's value of the UsageDetail entity.
+// If the UsageDetail 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 *UsageDetailMutation) OldReceiverID(ctx context.Context) (v string, err error) {
+	if !m.op.Is(OpUpdateOne) {
+		return v, errors.New("OldReceiverID is only allowed on UpdateOne operations")
+	}
+	if m.id == nil || m.oldValue == nil {
+		return v, errors.New("OldReceiverID requires an ID field in the mutation")
+	}
+	oldValue, err := m.oldValue(ctx)
+	if err != nil {
+		return v, fmt.Errorf("querying old value for OldReceiverID: %w", err)
+	}
+	return oldValue.ReceiverID, nil
+}
+
+// ResetReceiverID resets all changes to the "receiver_id" field.
+func (m *UsageDetailMutation) ResetReceiverID() {
+	m.receiver_id = nil
+}
+
+// SetApp sets the "app" field.
+func (m *UsageDetailMutation) SetApp(i int) {
+	m.app = &i
+	m.addapp = nil
+}
+
+// App returns the value of the "app" field in the mutation.
+func (m *UsageDetailMutation) App() (r int, exists bool) {
+	v := m.app
+	if v == nil {
+		return
+	}
+	return *v, true
+}
+
+// OldApp returns the old "app" field's value of the UsageDetail entity.
+// If the UsageDetail 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 *UsageDetailMutation) OldApp(ctx context.Context) (v int, err error) {
+	if !m.op.Is(OpUpdateOne) {
+		return v, errors.New("OldApp is only allowed on UpdateOne operations")
+	}
+	if m.id == nil || m.oldValue == nil {
+		return v, errors.New("OldApp requires an ID field in the mutation")
+	}
+	oldValue, err := m.oldValue(ctx)
+	if err != nil {
+		return v, fmt.Errorf("querying old value for OldApp: %w", err)
+	}
+	return oldValue.App, nil
+}
+
+// AddApp adds i to the "app" field.
+func (m *UsageDetailMutation) AddApp(i int) {
+	if m.addapp != nil {
+		*m.addapp += i
+	} else {
+		m.addapp = &i
+	}
+}
+
+// AddedApp returns the value that was added to the "app" field in this mutation.
+func (m *UsageDetailMutation) AddedApp() (r int, exists bool) {
+	v := m.addapp
+	if v == nil {
+		return
+	}
+	return *v, true
+}
+
+// ClearApp clears the value of the "app" field.
+func (m *UsageDetailMutation) ClearApp() {
+	m.app = nil
+	m.addapp = nil
+	m.clearedFields[usagedetail.FieldApp] = struct{}{}
+}
+
+// AppCleared returns if the "app" field was cleared in this mutation.
+func (m *UsageDetailMutation) AppCleared() bool {
+	_, ok := m.clearedFields[usagedetail.FieldApp]
+	return ok
+}
+
+// ResetApp resets all changes to the "app" field.
+func (m *UsageDetailMutation) ResetApp() {
+	m.app = nil
+	m.addapp = nil
+	delete(m.clearedFields, usagedetail.FieldApp)
+}
+
+// SetSessionID sets the "session_id" field.
+func (m *UsageDetailMutation) SetSessionID(u uint64) {
+	m.session_id = &u
+	m.addsession_id = nil
+}
+
+// SessionID returns the value of the "session_id" field in the mutation.
+func (m *UsageDetailMutation) SessionID() (r uint64, exists bool) {
+	v := m.session_id
+	if v == nil {
+		return
+	}
+	return *v, true
+}
+
+// OldSessionID returns the old "session_id" field's value of the UsageDetail entity.
+// If the UsageDetail 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 *UsageDetailMutation) OldSessionID(ctx context.Context) (v uint64, err error) {
+	if !m.op.Is(OpUpdateOne) {
+		return v, errors.New("OldSessionID is only allowed on UpdateOne operations")
+	}
+	if m.id == nil || m.oldValue == nil {
+		return v, errors.New("OldSessionID requires an ID field in the mutation")
+	}
+	oldValue, err := m.oldValue(ctx)
+	if err != nil {
+		return v, fmt.Errorf("querying old value for OldSessionID: %w", err)
+	}
+	return oldValue.SessionID, nil
+}
+
+// AddSessionID adds u to the "session_id" field.
+func (m *UsageDetailMutation) AddSessionID(u int64) {
+	if m.addsession_id != nil {
+		*m.addsession_id += u
+	} else {
+		m.addsession_id = &u
+	}
+}
+
+// AddedSessionID returns the value that was added to the "session_id" field in this mutation.
+func (m *UsageDetailMutation) AddedSessionID() (r int64, exists bool) {
+	v := m.addsession_id
+	if v == nil {
+		return
+	}
+	return *v, true
+}
+
+// ClearSessionID clears the value of the "session_id" field.
+func (m *UsageDetailMutation) ClearSessionID() {
+	m.session_id = nil
+	m.addsession_id = nil
+	m.clearedFields[usagedetail.FieldSessionID] = struct{}{}
+}
+
+// SessionIDCleared returns if the "session_id" field was cleared in this mutation.
+func (m *UsageDetailMutation) SessionIDCleared() bool {
+	_, ok := m.clearedFields[usagedetail.FieldSessionID]
+	return ok
+}
+
+// ResetSessionID resets all changes to the "session_id" field.
+func (m *UsageDetailMutation) ResetSessionID() {
+	m.session_id = nil
+	m.addsession_id = nil
+	delete(m.clearedFields, usagedetail.FieldSessionID)
+}
+
+// SetRequest sets the "request" field.
+func (m *UsageDetailMutation) SetRequest(s string) {
+	m.request = &s
+}
+
+// Request returns the value of the "request" field in the mutation.
+func (m *UsageDetailMutation) Request() (r string, exists bool) {
+	v := m.request
+	if v == nil {
+		return
+	}
+	return *v, true
+}
+
+// OldRequest returns the old "request" field's value of the UsageDetail entity.
+// If the UsageDetail 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 *UsageDetailMutation) OldRequest(ctx context.Context) (v string, err error) {
+	if !m.op.Is(OpUpdateOne) {
+		return v, errors.New("OldRequest is only allowed on UpdateOne operations")
+	}
+	if m.id == nil || m.oldValue == nil {
+		return v, errors.New("OldRequest requires an ID field in the mutation")
+	}
+	oldValue, err := m.oldValue(ctx)
+	if err != nil {
+		return v, fmt.Errorf("querying old value for OldRequest: %w", err)
+	}
+	return oldValue.Request, nil
+}
+
+// ResetRequest resets all changes to the "request" field.
+func (m *UsageDetailMutation) ResetRequest() {
+	m.request = nil
+}
+
+// SetResponse sets the "response" field.
+func (m *UsageDetailMutation) SetResponse(s string) {
+	m.response = &s
+}
+
+// Response returns the value of the "response" field in the mutation.
+func (m *UsageDetailMutation) Response() (r string, exists bool) {
+	v := m.response
+	if v == nil {
+		return
+	}
+	return *v, true
+}
+
+// OldResponse returns the old "response" field's value of the UsageDetail entity.
+// If the UsageDetail 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 *UsageDetailMutation) OldResponse(ctx context.Context) (v string, err error) {
+	if !m.op.Is(OpUpdateOne) {
+		return v, errors.New("OldResponse is only allowed on UpdateOne operations")
+	}
+	if m.id == nil || m.oldValue == nil {
+		return v, errors.New("OldResponse requires an ID field in the mutation")
+	}
+	oldValue, err := m.oldValue(ctx)
+	if err != nil {
+		return v, fmt.Errorf("querying old value for OldResponse: %w", err)
+	}
+	return oldValue.Response, nil
+}
+
+// ResetResponse resets all changes to the "response" field.
+func (m *UsageDetailMutation) ResetResponse() {
+	m.response = nil
+}
+
+// SetTotalTokens sets the "total_tokens" field.
+func (m *UsageDetailMutation) SetTotalTokens(u uint64) {
+	m.total_tokens = &u
+	m.addtotal_tokens = nil
+}
+
+// TotalTokens returns the value of the "total_tokens" field in the mutation.
+func (m *UsageDetailMutation) TotalTokens() (r uint64, exists bool) {
+	v := m.total_tokens
+	if v == nil {
+		return
+	}
+	return *v, true
+}
+
+// OldTotalTokens returns the old "total_tokens" field's value of the UsageDetail entity.
+// If the UsageDetail 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 *UsageDetailMutation) OldTotalTokens(ctx context.Context) (v uint64, err error) {
+	if !m.op.Is(OpUpdateOne) {
+		return v, errors.New("OldTotalTokens is only allowed on UpdateOne operations")
+	}
+	if m.id == nil || m.oldValue == nil {
+		return v, errors.New("OldTotalTokens requires an ID field in the mutation")
+	}
+	oldValue, err := m.oldValue(ctx)
+	if err != nil {
+		return v, fmt.Errorf("querying old value for OldTotalTokens: %w", err)
+	}
+	return oldValue.TotalTokens, nil
+}
+
+// AddTotalTokens adds u to the "total_tokens" field.
+func (m *UsageDetailMutation) AddTotalTokens(u int64) {
+	if m.addtotal_tokens != nil {
+		*m.addtotal_tokens += u
+	} else {
+		m.addtotal_tokens = &u
+	}
+}
+
+// AddedTotalTokens returns the value that was added to the "total_tokens" field in this mutation.
+func (m *UsageDetailMutation) AddedTotalTokens() (r int64, exists bool) {
+	v := m.addtotal_tokens
+	if v == nil {
+		return
+	}
+	return *v, true
+}
+
+// ClearTotalTokens clears the value of the "total_tokens" field.
+func (m *UsageDetailMutation) ClearTotalTokens() {
+	m.total_tokens = nil
+	m.addtotal_tokens = nil
+	m.clearedFields[usagedetail.FieldTotalTokens] = struct{}{}
+}
+
+// TotalTokensCleared returns if the "total_tokens" field was cleared in this mutation.
+func (m *UsageDetailMutation) TotalTokensCleared() bool {
+	_, ok := m.clearedFields[usagedetail.FieldTotalTokens]
+	return ok
+}
+
+// ResetTotalTokens resets all changes to the "total_tokens" field.
+func (m *UsageDetailMutation) ResetTotalTokens() {
+	m.total_tokens = nil
+	m.addtotal_tokens = nil
+	delete(m.clearedFields, usagedetail.FieldTotalTokens)
+}
+
+// SetPromptTokens sets the "prompt_tokens" field.
+func (m *UsageDetailMutation) SetPromptTokens(u uint64) {
+	m.prompt_tokens = &u
+	m.addprompt_tokens = nil
+}
+
+// PromptTokens returns the value of the "prompt_tokens" field in the mutation.
+func (m *UsageDetailMutation) PromptTokens() (r uint64, exists bool) {
+	v := m.prompt_tokens
+	if v == nil {
+		return
+	}
+	return *v, true
+}
+
+// OldPromptTokens returns the old "prompt_tokens" field's value of the UsageDetail entity.
+// If the UsageDetail 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 *UsageDetailMutation) OldPromptTokens(ctx context.Context) (v uint64, err error) {
+	if !m.op.Is(OpUpdateOne) {
+		return v, errors.New("OldPromptTokens is only allowed on UpdateOne operations")
+	}
+	if m.id == nil || m.oldValue == nil {
+		return v, errors.New("OldPromptTokens requires an ID field in the mutation")
+	}
+	oldValue, err := m.oldValue(ctx)
+	if err != nil {
+		return v, fmt.Errorf("querying old value for OldPromptTokens: %w", err)
+	}
+	return oldValue.PromptTokens, nil
+}
+
+// AddPromptTokens adds u to the "prompt_tokens" field.
+func (m *UsageDetailMutation) AddPromptTokens(u int64) {
+	if m.addprompt_tokens != nil {
+		*m.addprompt_tokens += u
+	} else {
+		m.addprompt_tokens = &u
+	}
+}
+
+// AddedPromptTokens returns the value that was added to the "prompt_tokens" field in this mutation.
+func (m *UsageDetailMutation) AddedPromptTokens() (r int64, exists bool) {
+	v := m.addprompt_tokens
+	if v == nil {
+		return
+	}
+	return *v, true
+}
+
+// ClearPromptTokens clears the value of the "prompt_tokens" field.
+func (m *UsageDetailMutation) ClearPromptTokens() {
+	m.prompt_tokens = nil
+	m.addprompt_tokens = nil
+	m.clearedFields[usagedetail.FieldPromptTokens] = struct{}{}
+}
+
+// PromptTokensCleared returns if the "prompt_tokens" field was cleared in this mutation.
+func (m *UsageDetailMutation) PromptTokensCleared() bool {
+	_, ok := m.clearedFields[usagedetail.FieldPromptTokens]
+	return ok
+}
+
+// ResetPromptTokens resets all changes to the "prompt_tokens" field.
+func (m *UsageDetailMutation) ResetPromptTokens() {
+	m.prompt_tokens = nil
+	m.addprompt_tokens = nil
+	delete(m.clearedFields, usagedetail.FieldPromptTokens)
+}
+
+// SetCompletionTokens sets the "completion_tokens" field.
+func (m *UsageDetailMutation) SetCompletionTokens(u uint64) {
+	m.completion_tokens = &u
+	m.addcompletion_tokens = nil
+}
+
+// CompletionTokens returns the value of the "completion_tokens" field in the mutation.
+func (m *UsageDetailMutation) CompletionTokens() (r uint64, exists bool) {
+	v := m.completion_tokens
+	if v == nil {
+		return
+	}
+	return *v, true
+}
+
+// OldCompletionTokens returns the old "completion_tokens" field's value of the UsageDetail entity.
+// If the UsageDetail 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 *UsageDetailMutation) OldCompletionTokens(ctx context.Context) (v uint64, err error) {
+	if !m.op.Is(OpUpdateOne) {
+		return v, errors.New("OldCompletionTokens is only allowed on UpdateOne operations")
+	}
+	if m.id == nil || m.oldValue == nil {
+		return v, errors.New("OldCompletionTokens requires an ID field in the mutation")
+	}
+	oldValue, err := m.oldValue(ctx)
+	if err != nil {
+		return v, fmt.Errorf("querying old value for OldCompletionTokens: %w", err)
+	}
+	return oldValue.CompletionTokens, nil
+}
+
+// AddCompletionTokens adds u to the "completion_tokens" field.
+func (m *UsageDetailMutation) AddCompletionTokens(u int64) {
+	if m.addcompletion_tokens != nil {
+		*m.addcompletion_tokens += u
+	} else {
+		m.addcompletion_tokens = &u
+	}
+}
+
+// AddedCompletionTokens returns the value that was added to the "completion_tokens" field in this mutation.
+func (m *UsageDetailMutation) AddedCompletionTokens() (r int64, exists bool) {
+	v := m.addcompletion_tokens
+	if v == nil {
+		return
+	}
+	return *v, true
+}
+
+// ClearCompletionTokens clears the value of the "completion_tokens" field.
+func (m *UsageDetailMutation) ClearCompletionTokens() {
+	m.completion_tokens = nil
+	m.addcompletion_tokens = nil
+	m.clearedFields[usagedetail.FieldCompletionTokens] = struct{}{}
+}
+
+// CompletionTokensCleared returns if the "completion_tokens" field was cleared in this mutation.
+func (m *UsageDetailMutation) CompletionTokensCleared() bool {
+	_, ok := m.clearedFields[usagedetail.FieldCompletionTokens]
+	return ok
+}
+
+// ResetCompletionTokens resets all changes to the "completion_tokens" field.
+func (m *UsageDetailMutation) ResetCompletionTokens() {
+	m.completion_tokens = nil
+	m.addcompletion_tokens = nil
+	delete(m.clearedFields, usagedetail.FieldCompletionTokens)
+}
+
+// SetOrganizationID sets the "organization_id" field.
+func (m *UsageDetailMutation) SetOrganizationID(u uint64) {
+	m.organization_id = &u
+	m.addorganization_id = nil
+}
+
+// OrganizationID returns the value of the "organization_id" field in the mutation.
+func (m *UsageDetailMutation) OrganizationID() (r uint64, exists bool) {
+	v := m.organization_id
+	if v == nil {
+		return
+	}
+	return *v, true
+}
+
+// OldOrganizationID returns the old "organization_id" field's value of the UsageDetail entity.
+// If the UsageDetail 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 *UsageDetailMutation) OldOrganizationID(ctx context.Context) (v uint64, err error) {
+	if !m.op.Is(OpUpdateOne) {
+		return v, errors.New("OldOrganizationID is only allowed on UpdateOne operations")
+	}
+	if m.id == nil || m.oldValue == nil {
+		return v, errors.New("OldOrganizationID requires an ID field in the mutation")
+	}
+	oldValue, err := m.oldValue(ctx)
+	if err != nil {
+		return v, fmt.Errorf("querying old value for OldOrganizationID: %w", err)
+	}
+	return oldValue.OrganizationID, nil
+}
+
+// AddOrganizationID adds u to the "organization_id" field.
+func (m *UsageDetailMutation) AddOrganizationID(u int64) {
+	if m.addorganization_id != nil {
+		*m.addorganization_id += u
+	} else {
+		m.addorganization_id = &u
+	}
+}
+
+// AddedOrganizationID returns the value that was added to the "organization_id" field in this mutation.
+func (m *UsageDetailMutation) AddedOrganizationID() (r int64, exists bool) {
+	v := m.addorganization_id
+	if v == nil {
+		return
+	}
+	return *v, true
+}
+
+// ClearOrganizationID clears the value of the "organization_id" field.
+func (m *UsageDetailMutation) ClearOrganizationID() {
+	m.organization_id = nil
+	m.addorganization_id = nil
+	m.clearedFields[usagedetail.FieldOrganizationID] = struct{}{}
+}
+
+// OrganizationIDCleared returns if the "organization_id" field was cleared in this mutation.
+func (m *UsageDetailMutation) OrganizationIDCleared() bool {
+	_, ok := m.clearedFields[usagedetail.FieldOrganizationID]
+	return ok
+}
+
+// ResetOrganizationID resets all changes to the "organization_id" field.
+func (m *UsageDetailMutation) ResetOrganizationID() {
+	m.organization_id = nil
+	m.addorganization_id = nil
+	delete(m.clearedFields, usagedetail.FieldOrganizationID)
+}
+
+// Where appends a list predicates to the UsageDetailMutation builder.
+func (m *UsageDetailMutation) Where(ps ...predicate.UsageDetail) {
+	m.predicates = append(m.predicates, ps...)
+}
+
+// WhereP appends storage-level predicates to the UsageDetailMutation builder. Using this method,
+// users can use type-assertion to append predicates that do not depend on any generated package.
+func (m *UsageDetailMutation) WhereP(ps ...func(*sql.Selector)) {
+	p := make([]predicate.UsageDetail, len(ps))
+	for i := range ps {
+		p[i] = ps[i]
+	}
+	m.Where(p...)
+}
+
+// Op returns the operation name.
+func (m *UsageDetailMutation) Op() Op {
+	return m.op
+}
+
+// SetOp allows setting the mutation operation.
+func (m *UsageDetailMutation) SetOp(op Op) {
+	m.op = op
+}
+
+// Type returns the node type of this mutation (UsageDetail).
+func (m *UsageDetailMutation) 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 *UsageDetailMutation) Fields() []string {
+	fields := make([]string, 0, 14)
+	if m.created_at != nil {
+		fields = append(fields, usagedetail.FieldCreatedAt)
+	}
+	if m.updated_at != nil {
+		fields = append(fields, usagedetail.FieldUpdatedAt)
+	}
+	if m.status != nil {
+		fields = append(fields, usagedetail.FieldStatus)
+	}
+	if m._type != nil {
+		fields = append(fields, usagedetail.FieldType)
+	}
+	if m.bot_id != nil {
+		fields = append(fields, usagedetail.FieldBotID)
+	}
+	if m.receiver_id != nil {
+		fields = append(fields, usagedetail.FieldReceiverID)
+	}
+	if m.app != nil {
+		fields = append(fields, usagedetail.FieldApp)
+	}
+	if m.session_id != nil {
+		fields = append(fields, usagedetail.FieldSessionID)
+	}
+	if m.request != nil {
+		fields = append(fields, usagedetail.FieldRequest)
+	}
+	if m.response != nil {
+		fields = append(fields, usagedetail.FieldResponse)
+	}
+	if m.total_tokens != nil {
+		fields = append(fields, usagedetail.FieldTotalTokens)
+	}
+	if m.prompt_tokens != nil {
+		fields = append(fields, usagedetail.FieldPromptTokens)
+	}
+	if m.completion_tokens != nil {
+		fields = append(fields, usagedetail.FieldCompletionTokens)
+	}
+	if m.organization_id != nil {
+		fields = append(fields, usagedetail.FieldOrganizationID)
+	}
+	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 *UsageDetailMutation) Field(name string) (ent.Value, bool) {
+	switch name {
+	case usagedetail.FieldCreatedAt:
+		return m.CreatedAt()
+	case usagedetail.FieldUpdatedAt:
+		return m.UpdatedAt()
+	case usagedetail.FieldStatus:
+		return m.Status()
+	case usagedetail.FieldType:
+		return m.GetType()
+	case usagedetail.FieldBotID:
+		return m.BotID()
+	case usagedetail.FieldReceiverID:
+		return m.ReceiverID()
+	case usagedetail.FieldApp:
+		return m.App()
+	case usagedetail.FieldSessionID:
+		return m.SessionID()
+	case usagedetail.FieldRequest:
+		return m.Request()
+	case usagedetail.FieldResponse:
+		return m.Response()
+	case usagedetail.FieldTotalTokens:
+		return m.TotalTokens()
+	case usagedetail.FieldPromptTokens:
+		return m.PromptTokens()
+	case usagedetail.FieldCompletionTokens:
+		return m.CompletionTokens()
+	case usagedetail.FieldOrganizationID:
+		return m.OrganizationID()
+	}
+	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 *UsageDetailMutation) OldField(ctx context.Context, name string) (ent.Value, error) {
+	switch name {
+	case usagedetail.FieldCreatedAt:
+		return m.OldCreatedAt(ctx)
+	case usagedetail.FieldUpdatedAt:
+		return m.OldUpdatedAt(ctx)
+	case usagedetail.FieldStatus:
+		return m.OldStatus(ctx)
+	case usagedetail.FieldType:
+		return m.OldType(ctx)
+	case usagedetail.FieldBotID:
+		return m.OldBotID(ctx)
+	case usagedetail.FieldReceiverID:
+		return m.OldReceiverID(ctx)
+	case usagedetail.FieldApp:
+		return m.OldApp(ctx)
+	case usagedetail.FieldSessionID:
+		return m.OldSessionID(ctx)
+	case usagedetail.FieldRequest:
+		return m.OldRequest(ctx)
+	case usagedetail.FieldResponse:
+		return m.OldResponse(ctx)
+	case usagedetail.FieldTotalTokens:
+		return m.OldTotalTokens(ctx)
+	case usagedetail.FieldPromptTokens:
+		return m.OldPromptTokens(ctx)
+	case usagedetail.FieldCompletionTokens:
+		return m.OldCompletionTokens(ctx)
+	case usagedetail.FieldOrganizationID:
+		return m.OldOrganizationID(ctx)
+	}
+	return nil, fmt.Errorf("unknown UsageDetail 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 *UsageDetailMutation) SetField(name string, value ent.Value) error {
+	switch name {
+	case usagedetail.FieldCreatedAt:
+		v, ok := value.(time.Time)
+		if !ok {
+			return fmt.Errorf("unexpected type %T for field %s", value, name)
+		}
+		m.SetCreatedAt(v)
+		return nil
+	case usagedetail.FieldUpdatedAt:
+		v, ok := value.(time.Time)
+		if !ok {
+			return fmt.Errorf("unexpected type %T for field %s", value, name)
+		}
+		m.SetUpdatedAt(v)
+		return nil
+	case usagedetail.FieldStatus:
+		v, ok := value.(uint8)
+		if !ok {
+			return fmt.Errorf("unexpected type %T for field %s", value, name)
+		}
+		m.SetStatus(v)
+		return nil
+	case usagedetail.FieldType:
+		v, ok := value.(int)
+		if !ok {
+			return fmt.Errorf("unexpected type %T for field %s", value, name)
+		}
+		m.SetType(v)
+		return nil
+	case usagedetail.FieldBotID:
+		v, ok := value.(string)
+		if !ok {
+			return fmt.Errorf("unexpected type %T for field %s", value, name)
+		}
+		m.SetBotID(v)
+		return nil
+	case usagedetail.FieldReceiverID:
+		v, ok := value.(string)
+		if !ok {
+			return fmt.Errorf("unexpected type %T for field %s", value, name)
+		}
+		m.SetReceiverID(v)
+		return nil
+	case usagedetail.FieldApp:
+		v, ok := value.(int)
+		if !ok {
+			return fmt.Errorf("unexpected type %T for field %s", value, name)
+		}
+		m.SetApp(v)
+		return nil
+	case usagedetail.FieldSessionID:
+		v, ok := value.(uint64)
+		if !ok {
+			return fmt.Errorf("unexpected type %T for field %s", value, name)
+		}
+		m.SetSessionID(v)
+		return nil
+	case usagedetail.FieldRequest:
+		v, ok := value.(string)
+		if !ok {
+			return fmt.Errorf("unexpected type %T for field %s", value, name)
+		}
+		m.SetRequest(v)
+		return nil
+	case usagedetail.FieldResponse:
+		v, ok := value.(string)
+		if !ok {
+			return fmt.Errorf("unexpected type %T for field %s", value, name)
+		}
+		m.SetResponse(v)
+		return nil
+	case usagedetail.FieldTotalTokens:
+		v, ok := value.(uint64)
+		if !ok {
+			return fmt.Errorf("unexpected type %T for field %s", value, name)
+		}
+		m.SetTotalTokens(v)
+		return nil
+	case usagedetail.FieldPromptTokens:
+		v, ok := value.(uint64)
+		if !ok {
+			return fmt.Errorf("unexpected type %T for field %s", value, name)
+		}
+		m.SetPromptTokens(v)
+		return nil
+	case usagedetail.FieldCompletionTokens:
+		v, ok := value.(uint64)
+		if !ok {
+			return fmt.Errorf("unexpected type %T for field %s", value, name)
+		}
+		m.SetCompletionTokens(v)
+		return nil
+	case usagedetail.FieldOrganizationID:
+		v, ok := value.(uint64)
+		if !ok {
+			return fmt.Errorf("unexpected type %T for field %s", value, name)
+		}
+		m.SetOrganizationID(v)
+		return nil
+	}
+	return fmt.Errorf("unknown UsageDetail field %s", name)
+}
+
+// AddedFields returns all numeric fields that were incremented/decremented during
+// this mutation.
+func (m *UsageDetailMutation) AddedFields() []string {
+	var fields []string
+	if m.addstatus != nil {
+		fields = append(fields, usagedetail.FieldStatus)
+	}
+	if m.add_type != nil {
+		fields = append(fields, usagedetail.FieldType)
+	}
+	if m.addapp != nil {
+		fields = append(fields, usagedetail.FieldApp)
+	}
+	if m.addsession_id != nil {
+		fields = append(fields, usagedetail.FieldSessionID)
+	}
+	if m.addtotal_tokens != nil {
+		fields = append(fields, usagedetail.FieldTotalTokens)
+	}
+	if m.addprompt_tokens != nil {
+		fields = append(fields, usagedetail.FieldPromptTokens)
+	}
+	if m.addcompletion_tokens != nil {
+		fields = append(fields, usagedetail.FieldCompletionTokens)
+	}
+	if m.addorganization_id != nil {
+		fields = append(fields, usagedetail.FieldOrganizationID)
+	}
+	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 *UsageDetailMutation) AddedField(name string) (ent.Value, bool) {
+	switch name {
+	case usagedetail.FieldStatus:
+		return m.AddedStatus()
+	case usagedetail.FieldType:
+		return m.AddedType()
+	case usagedetail.FieldApp:
+		return m.AddedApp()
+	case usagedetail.FieldSessionID:
+		return m.AddedSessionID()
+	case usagedetail.FieldTotalTokens:
+		return m.AddedTotalTokens()
+	case usagedetail.FieldPromptTokens:
+		return m.AddedPromptTokens()
+	case usagedetail.FieldCompletionTokens:
+		return m.AddedCompletionTokens()
+	case usagedetail.FieldOrganizationID:
+		return m.AddedOrganizationID()
+	}
+	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 *UsageDetailMutation) AddField(name string, value ent.Value) error {
+	switch name {
+	case usagedetail.FieldStatus:
+		v, ok := value.(int8)
+		if !ok {
+			return fmt.Errorf("unexpected type %T for field %s", value, name)
+		}
+		m.AddStatus(v)
+		return nil
+	case usagedetail.FieldType:
+		v, ok := value.(int)
+		if !ok {
+			return fmt.Errorf("unexpected type %T for field %s", value, name)
+		}
+		m.AddType(v)
+		return nil
+	case usagedetail.FieldApp:
+		v, ok := value.(int)
+		if !ok {
+			return fmt.Errorf("unexpected type %T for field %s", value, name)
+		}
+		m.AddApp(v)
+		return nil
+	case usagedetail.FieldSessionID:
+		v, ok := value.(int64)
+		if !ok {
+			return fmt.Errorf("unexpected type %T for field %s", value, name)
+		}
+		m.AddSessionID(v)
+		return nil
+	case usagedetail.FieldTotalTokens:
+		v, ok := value.(int64)
+		if !ok {
+			return fmt.Errorf("unexpected type %T for field %s", value, name)
+		}
+		m.AddTotalTokens(v)
+		return nil
+	case usagedetail.FieldPromptTokens:
+		v, ok := value.(int64)
+		if !ok {
+			return fmt.Errorf("unexpected type %T for field %s", value, name)
+		}
+		m.AddPromptTokens(v)
+		return nil
+	case usagedetail.FieldCompletionTokens:
+		v, ok := value.(int64)
+		if !ok {
+			return fmt.Errorf("unexpected type %T for field %s", value, name)
+		}
+		m.AddCompletionTokens(v)
+		return nil
+	case usagedetail.FieldOrganizationID:
+		v, ok := value.(int64)
+		if !ok {
+			return fmt.Errorf("unexpected type %T for field %s", value, name)
+		}
+		m.AddOrganizationID(v)
+		return nil
+	}
+	return fmt.Errorf("unknown UsageDetail numeric field %s", name)
+}
+
+// ClearedFields returns all nullable fields that were cleared during this
+// mutation.
+func (m *UsageDetailMutation) ClearedFields() []string {
+	var fields []string
+	if m.FieldCleared(usagedetail.FieldStatus) {
+		fields = append(fields, usagedetail.FieldStatus)
+	}
+	if m.FieldCleared(usagedetail.FieldType) {
+		fields = append(fields, usagedetail.FieldType)
+	}
+	if m.FieldCleared(usagedetail.FieldApp) {
+		fields = append(fields, usagedetail.FieldApp)
+	}
+	if m.FieldCleared(usagedetail.FieldSessionID) {
+		fields = append(fields, usagedetail.FieldSessionID)
+	}
+	if m.FieldCleared(usagedetail.FieldTotalTokens) {
+		fields = append(fields, usagedetail.FieldTotalTokens)
+	}
+	if m.FieldCleared(usagedetail.FieldPromptTokens) {
+		fields = append(fields, usagedetail.FieldPromptTokens)
+	}
+	if m.FieldCleared(usagedetail.FieldCompletionTokens) {
+		fields = append(fields, usagedetail.FieldCompletionTokens)
+	}
+	if m.FieldCleared(usagedetail.FieldOrganizationID) {
+		fields = append(fields, usagedetail.FieldOrganizationID)
+	}
+	return fields
+}
+
+// FieldCleared returns a boolean indicating if a field with the given name was
+// cleared in this mutation.
+func (m *UsageDetailMutation) 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 *UsageDetailMutation) ClearField(name string) error {
+	switch name {
+	case usagedetail.FieldStatus:
+		m.ClearStatus()
+		return nil
+	case usagedetail.FieldType:
+		m.ClearType()
+		return nil
+	case usagedetail.FieldApp:
+		m.ClearApp()
+		return nil
+	case usagedetail.FieldSessionID:
+		m.ClearSessionID()
+		return nil
+	case usagedetail.FieldTotalTokens:
+		m.ClearTotalTokens()
+		return nil
+	case usagedetail.FieldPromptTokens:
+		m.ClearPromptTokens()
+		return nil
+	case usagedetail.FieldCompletionTokens:
+		m.ClearCompletionTokens()
+		return nil
+	case usagedetail.FieldOrganizationID:
+		m.ClearOrganizationID()
+		return nil
+	}
+	return fmt.Errorf("unknown UsageDetail 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 *UsageDetailMutation) ResetField(name string) error {
+	switch name {
+	case usagedetail.FieldCreatedAt:
+		m.ResetCreatedAt()
+		return nil
+	case usagedetail.FieldUpdatedAt:
+		m.ResetUpdatedAt()
+		return nil
+	case usagedetail.FieldStatus:
+		m.ResetStatus()
+		return nil
+	case usagedetail.FieldType:
+		m.ResetType()
+		return nil
+	case usagedetail.FieldBotID:
+		m.ResetBotID()
+		return nil
+	case usagedetail.FieldReceiverID:
+		m.ResetReceiverID()
+		return nil
+	case usagedetail.FieldApp:
+		m.ResetApp()
+		return nil
+	case usagedetail.FieldSessionID:
+		m.ResetSessionID()
+		return nil
+	case usagedetail.FieldRequest:
+		m.ResetRequest()
+		return nil
+	case usagedetail.FieldResponse:
+		m.ResetResponse()
+		return nil
+	case usagedetail.FieldTotalTokens:
+		m.ResetTotalTokens()
+		return nil
+	case usagedetail.FieldPromptTokens:
+		m.ResetPromptTokens()
+		return nil
+	case usagedetail.FieldCompletionTokens:
+		m.ResetCompletionTokens()
+		return nil
+	case usagedetail.FieldOrganizationID:
+		m.ResetOrganizationID()
+		return nil
+	}
+	return fmt.Errorf("unknown UsageDetail field %s", name)
+}
+
+// AddedEdges returns all edge names that were set/added in this mutation.
+func (m *UsageDetailMutation) AddedEdges() []string {
+	edges := make([]string, 0, 0)
+	return edges
+}
+
+// AddedIDs returns all IDs (to other nodes) that were added for the given edge
+// name in this mutation.
+func (m *UsageDetailMutation) AddedIDs(name string) []ent.Value {
+	return nil
+}
+
+// RemovedEdges returns all edge names that were removed in this mutation.
+func (m *UsageDetailMutation) RemovedEdges() []string {
+	edges := make([]string, 0, 0)
+	return edges
+}
+
+// RemovedIDs returns all IDs (to other nodes) that were removed for the edge with
+// the given name in this mutation.
+func (m *UsageDetailMutation) RemovedIDs(name string) []ent.Value {
+	return nil
+}
+
+// ClearedEdges returns all edge names that were cleared in this mutation.
+func (m *UsageDetailMutation) ClearedEdges() []string {
+	edges := make([]string, 0, 0)
+	return edges
+}
+
+// EdgeCleared returns a boolean which indicates if the edge with the given name
+// was cleared in this mutation.
+func (m *UsageDetailMutation) EdgeCleared(name string) bool {
+	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 *UsageDetailMutation) ClearEdge(name string) error {
+	return fmt.Errorf("unknown UsageDetail 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 *UsageDetailMutation) ResetEdge(name string) error {
+	return fmt.Errorf("unknown UsageDetail edge %s", name)
+}
+
+// UsageTotalMutation represents an operation that mutates the UsageTotal nodes in the graph.
+type UsageTotalMutation struct {
+	config
+	op                 Op
+	typ                string
+	id                 *uint64
+	created_at         *time.Time
+	updated_at         *time.Time
+	status             *uint8
+	addstatus          *int8
+	_type              *int
+	add_type           *int
+	bot_id             *string
+	total_tokens       *uint64
+	addtotal_tokens    *int64
+	start_index        *uint64
+	addstart_index     *int64
+	end_index          *uint64
+	addend_index       *int64
+	organization_id    *uint64
+	addorganization_id *int64
+	clearedFields      map[string]struct{}
+	done               bool
+	oldValue           func(context.Context) (*UsageTotal, error)
+	predicates         []predicate.UsageTotal
+}
+
+var _ ent.Mutation = (*UsageTotalMutation)(nil)
+
+// usagetotalOption allows management of the mutation configuration using functional options.
+type usagetotalOption func(*UsageTotalMutation)
+
+// newUsageTotalMutation creates new mutation for the UsageTotal entity.
+func newUsageTotalMutation(c config, op Op, opts ...usagetotalOption) *UsageTotalMutation {
+	m := &UsageTotalMutation{
+		config:        c,
+		op:            op,
+		typ:           TypeUsageTotal,
+		clearedFields: make(map[string]struct{}),
+	}
+	for _, opt := range opts {
+		opt(m)
+	}
+	return m
+}
+
+// withUsageTotalID sets the ID field of the mutation.
+func withUsageTotalID(id uint64) usagetotalOption {
+	return func(m *UsageTotalMutation) {
+		var (
+			err   error
+			once  sync.Once
+			value *UsageTotal
+		)
+		m.oldValue = func(ctx context.Context) (*UsageTotal, error) {
+			once.Do(func() {
+				if m.done {
+					err = errors.New("querying old values post mutation is not allowed")
+				} else {
+					value, err = m.Client().UsageTotal.Get(ctx, id)
+				}
+			})
+			return value, err
+		}
+		m.id = &id
+	}
+}
+
+// withUsageTotal sets the old UsageTotal of the mutation.
+func withUsageTotal(node *UsageTotal) usagetotalOption {
+	return func(m *UsageTotalMutation) {
+		m.oldValue = func(context.Context) (*UsageTotal, 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 UsageTotalMutation) 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 UsageTotalMutation) 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 UsageTotal entities.
+func (m *UsageTotalMutation) SetID(id uint64) {
+	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 *UsageTotalMutation) ID() (id uint64, 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 *UsageTotalMutation) IDs(ctx context.Context) ([]uint64, error) {
+	switch {
+	case m.op.Is(OpUpdateOne | OpDeleteOne):
+		id, exists := m.ID()
+		if exists {
+			return []uint64{id}, nil
+		}
+		fallthrough
+	case m.op.Is(OpUpdate | OpDelete):
+		return m.Client().UsageTotal.Query().Where(m.predicates...).IDs(ctx)
+	default:
+		return nil, fmt.Errorf("IDs is not allowed on %s operations", m.op)
+	}
+}
+
+// SetCreatedAt sets the "created_at" field.
+func (m *UsageTotalMutation) SetCreatedAt(t time.Time) {
+	m.created_at = &t
+}
+
+// CreatedAt returns the value of the "created_at" field in the mutation.
+func (m *UsageTotalMutation) CreatedAt() (r time.Time, exists bool) {
+	v := m.created_at
+	if v == nil {
+		return
+	}
+	return *v, true
+}
+
+// OldCreatedAt returns the old "created_at" field's value of the UsageTotal entity.
+// If the UsageTotal 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 *UsageTotalMutation) OldCreatedAt(ctx context.Context) (v time.Time, err error) {
+	if !m.op.Is(OpUpdateOne) {
+		return v, errors.New("OldCreatedAt is only allowed on UpdateOne operations")
+	}
+	if m.id == nil || m.oldValue == nil {
+		return v, errors.New("OldCreatedAt requires an ID field in the mutation")
+	}
+	oldValue, err := m.oldValue(ctx)
+	if err != nil {
+		return v, fmt.Errorf("querying old value for OldCreatedAt: %w", err)
+	}
+	return oldValue.CreatedAt, nil
+}
+
+// ResetCreatedAt resets all changes to the "created_at" field.
+func (m *UsageTotalMutation) ResetCreatedAt() {
+	m.created_at = nil
+}
+
+// SetUpdatedAt sets the "updated_at" field.
+func (m *UsageTotalMutation) SetUpdatedAt(t time.Time) {
+	m.updated_at = &t
+}
+
+// UpdatedAt returns the value of the "updated_at" field in the mutation.
+func (m *UsageTotalMutation) UpdatedAt() (r time.Time, exists bool) {
+	v := m.updated_at
+	if v == nil {
+		return
+	}
+	return *v, true
+}
+
+// OldUpdatedAt returns the old "updated_at" field's value of the UsageTotal entity.
+// If the UsageTotal 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 *UsageTotalMutation) OldUpdatedAt(ctx context.Context) (v time.Time, err error) {
+	if !m.op.Is(OpUpdateOne) {
+		return v, errors.New("OldUpdatedAt is only allowed on UpdateOne operations")
+	}
+	if m.id == nil || m.oldValue == nil {
+		return v, errors.New("OldUpdatedAt requires an ID field in the mutation")
+	}
+	oldValue, err := m.oldValue(ctx)
+	if err != nil {
+		return v, fmt.Errorf("querying old value for OldUpdatedAt: %w", err)
+	}
+	return oldValue.UpdatedAt, nil
+}
+
+// ResetUpdatedAt resets all changes to the "updated_at" field.
+func (m *UsageTotalMutation) ResetUpdatedAt() {
+	m.updated_at = nil
+}
+
+// SetStatus sets the "status" field.
+func (m *UsageTotalMutation) SetStatus(u uint8) {
+	m.status = &u
+	m.addstatus = nil
+}
+
+// Status returns the value of the "status" field in the mutation.
+func (m *UsageTotalMutation) Status() (r uint8, exists bool) {
+	v := m.status
+	if v == nil {
+		return
+	}
+	return *v, true
+}
+
+// OldStatus returns the old "status" field's value of the UsageTotal entity.
+// If the UsageTotal 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 *UsageTotalMutation) OldStatus(ctx context.Context) (v uint8, err error) {
+	if !m.op.Is(OpUpdateOne) {
+		return v, errors.New("OldStatus is only allowed on UpdateOne operations")
+	}
+	if m.id == nil || m.oldValue == nil {
+		return v, errors.New("OldStatus requires an ID field in the mutation")
+	}
+	oldValue, err := m.oldValue(ctx)
+	if err != nil {
+		return v, fmt.Errorf("querying old value for OldStatus: %w", err)
+	}
+	return oldValue.Status, nil
+}
+
+// AddStatus adds u to the "status" field.
+func (m *UsageTotalMutation) AddStatus(u int8) {
+	if m.addstatus != nil {
+		*m.addstatus += u
+	} else {
+		m.addstatus = &u
+	}
+}
+
+// AddedStatus returns the value that was added to the "status" field in this mutation.
+func (m *UsageTotalMutation) AddedStatus() (r int8, exists bool) {
+	v := m.addstatus
+	if v == nil {
+		return
+	}
+	return *v, true
+}
+
+// ClearStatus clears the value of the "status" field.
+func (m *UsageTotalMutation) ClearStatus() {
+	m.status = nil
+	m.addstatus = nil
+	m.clearedFields[usagetotal.FieldStatus] = struct{}{}
+}
+
+// StatusCleared returns if the "status" field was cleared in this mutation.
+func (m *UsageTotalMutation) StatusCleared() bool {
+	_, ok := m.clearedFields[usagetotal.FieldStatus]
+	return ok
+}
+
+// ResetStatus resets all changes to the "status" field.
+func (m *UsageTotalMutation) ResetStatus() {
+	m.status = nil
+	m.addstatus = nil
+	delete(m.clearedFields, usagetotal.FieldStatus)
+}
+
+// SetType sets the "type" field.
+func (m *UsageTotalMutation) SetType(i int) {
+	m._type = &i
+	m.add_type = nil
+}
+
+// GetType returns the value of the "type" field in the mutation.
+func (m *UsageTotalMutation) GetType() (r int, exists bool) {
+	v := m._type
+	if v == nil {
+		return
+	}
+	return *v, true
+}
+
+// OldType returns the old "type" field's value of the UsageTotal entity.
+// If the UsageTotal 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 *UsageTotalMutation) OldType(ctx context.Context) (v int, err error) {
+	if !m.op.Is(OpUpdateOne) {
+		return v, errors.New("OldType is only allowed on UpdateOne operations")
+	}
+	if m.id == nil || m.oldValue == nil {
+		return v, errors.New("OldType requires an ID field in the mutation")
+	}
+	oldValue, err := m.oldValue(ctx)
+	if err != nil {
+		return v, fmt.Errorf("querying old value for OldType: %w", err)
+	}
+	return oldValue.Type, nil
+}
+
+// AddType adds i to the "type" field.
+func (m *UsageTotalMutation) AddType(i int) {
+	if m.add_type != nil {
+		*m.add_type += i
+	} else {
+		m.add_type = &i
+	}
+}
+
+// AddedType returns the value that was added to the "type" field in this mutation.
+func (m *UsageTotalMutation) AddedType() (r int, exists bool) {
+	v := m.add_type
+	if v == nil {
+		return
+	}
+	return *v, true
+}
+
+// ClearType clears the value of the "type" field.
+func (m *UsageTotalMutation) ClearType() {
+	m._type = nil
+	m.add_type = nil
+	m.clearedFields[usagetotal.FieldType] = struct{}{}
+}
+
+// TypeCleared returns if the "type" field was cleared in this mutation.
+func (m *UsageTotalMutation) TypeCleared() bool {
+	_, ok := m.clearedFields[usagetotal.FieldType]
+	return ok
+}
+
+// ResetType resets all changes to the "type" field.
+func (m *UsageTotalMutation) ResetType() {
+	m._type = nil
+	m.add_type = nil
+	delete(m.clearedFields, usagetotal.FieldType)
+}
+
+// SetBotID sets the "bot_id" field.
+func (m *UsageTotalMutation) SetBotID(s string) {
+	m.bot_id = &s
+}
+
+// BotID returns the value of the "bot_id" field in the mutation.
+func (m *UsageTotalMutation) BotID() (r string, exists bool) {
+	v := m.bot_id
+	if v == nil {
+		return
+	}
+	return *v, true
+}
+
+// OldBotID returns the old "bot_id" field's value of the UsageTotal entity.
+// If the UsageTotal 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 *UsageTotalMutation) OldBotID(ctx context.Context) (v string, err error) {
+	if !m.op.Is(OpUpdateOne) {
+		return v, errors.New("OldBotID is only allowed on UpdateOne operations")
+	}
+	if m.id == nil || m.oldValue == nil {
+		return v, errors.New("OldBotID requires an ID field in the mutation")
+	}
+	oldValue, err := m.oldValue(ctx)
+	if err != nil {
+		return v, fmt.Errorf("querying old value for OldBotID: %w", err)
+	}
+	return oldValue.BotID, nil
+}
+
+// ResetBotID resets all changes to the "bot_id" field.
+func (m *UsageTotalMutation) ResetBotID() {
+	m.bot_id = nil
+}
+
+// SetTotalTokens sets the "total_tokens" field.
+func (m *UsageTotalMutation) SetTotalTokens(u uint64) {
+	m.total_tokens = &u
+	m.addtotal_tokens = nil
+}
+
+// TotalTokens returns the value of the "total_tokens" field in the mutation.
+func (m *UsageTotalMutation) TotalTokens() (r uint64, exists bool) {
+	v := m.total_tokens
+	if v == nil {
+		return
+	}
+	return *v, true
+}
+
+// OldTotalTokens returns the old "total_tokens" field's value of the UsageTotal entity.
+// If the UsageTotal 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 *UsageTotalMutation) OldTotalTokens(ctx context.Context) (v uint64, err error) {
+	if !m.op.Is(OpUpdateOne) {
+		return v, errors.New("OldTotalTokens is only allowed on UpdateOne operations")
+	}
+	if m.id == nil || m.oldValue == nil {
+		return v, errors.New("OldTotalTokens requires an ID field in the mutation")
+	}
+	oldValue, err := m.oldValue(ctx)
+	if err != nil {
+		return v, fmt.Errorf("querying old value for OldTotalTokens: %w", err)
+	}
+	return oldValue.TotalTokens, nil
+}
+
+// AddTotalTokens adds u to the "total_tokens" field.
+func (m *UsageTotalMutation) AddTotalTokens(u int64) {
+	if m.addtotal_tokens != nil {
+		*m.addtotal_tokens += u
+	} else {
+		m.addtotal_tokens = &u
+	}
+}
+
+// AddedTotalTokens returns the value that was added to the "total_tokens" field in this mutation.
+func (m *UsageTotalMutation) AddedTotalTokens() (r int64, exists bool) {
+	v := m.addtotal_tokens
+	if v == nil {
+		return
+	}
+	return *v, true
+}
+
+// ClearTotalTokens clears the value of the "total_tokens" field.
+func (m *UsageTotalMutation) ClearTotalTokens() {
+	m.total_tokens = nil
+	m.addtotal_tokens = nil
+	m.clearedFields[usagetotal.FieldTotalTokens] = struct{}{}
+}
+
+// TotalTokensCleared returns if the "total_tokens" field was cleared in this mutation.
+func (m *UsageTotalMutation) TotalTokensCleared() bool {
+	_, ok := m.clearedFields[usagetotal.FieldTotalTokens]
+	return ok
+}
+
+// ResetTotalTokens resets all changes to the "total_tokens" field.
+func (m *UsageTotalMutation) ResetTotalTokens() {
+	m.total_tokens = nil
+	m.addtotal_tokens = nil
+	delete(m.clearedFields, usagetotal.FieldTotalTokens)
+}
+
+// SetStartIndex sets the "start_index" field.
+func (m *UsageTotalMutation) SetStartIndex(u uint64) {
+	m.start_index = &u
+	m.addstart_index = nil
+}
+
+// StartIndex returns the value of the "start_index" field in the mutation.
+func (m *UsageTotalMutation) StartIndex() (r uint64, exists bool) {
+	v := m.start_index
+	if v == nil {
+		return
+	}
+	return *v, true
+}
+
+// OldStartIndex returns the old "start_index" field's value of the UsageTotal entity.
+// If the UsageTotal 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 *UsageTotalMutation) OldStartIndex(ctx context.Context) (v uint64, err error) {
+	if !m.op.Is(OpUpdateOne) {
+		return v, errors.New("OldStartIndex is only allowed on UpdateOne operations")
+	}
+	if m.id == nil || m.oldValue == nil {
+		return v, errors.New("OldStartIndex requires an ID field in the mutation")
+	}
+	oldValue, err := m.oldValue(ctx)
+	if err != nil {
+		return v, fmt.Errorf("querying old value for OldStartIndex: %w", err)
+	}
+	return oldValue.StartIndex, nil
+}
+
+// AddStartIndex adds u to the "start_index" field.
+func (m *UsageTotalMutation) AddStartIndex(u int64) {
+	if m.addstart_index != nil {
+		*m.addstart_index += u
+	} else {
+		m.addstart_index = &u
+	}
+}
+
+// AddedStartIndex returns the value that was added to the "start_index" field in this mutation.
+func (m *UsageTotalMutation) AddedStartIndex() (r int64, exists bool) {
+	v := m.addstart_index
+	if v == nil {
+		return
+	}
+	return *v, true
+}
+
+// ClearStartIndex clears the value of the "start_index" field.
+func (m *UsageTotalMutation) ClearStartIndex() {
+	m.start_index = nil
+	m.addstart_index = nil
+	m.clearedFields[usagetotal.FieldStartIndex] = struct{}{}
+}
+
+// StartIndexCleared returns if the "start_index" field was cleared in this mutation.
+func (m *UsageTotalMutation) StartIndexCleared() bool {
+	_, ok := m.clearedFields[usagetotal.FieldStartIndex]
+	return ok
+}
+
+// ResetStartIndex resets all changes to the "start_index" field.
+func (m *UsageTotalMutation) ResetStartIndex() {
+	m.start_index = nil
+	m.addstart_index = nil
+	delete(m.clearedFields, usagetotal.FieldStartIndex)
+}
+
+// SetEndIndex sets the "end_index" field.
+func (m *UsageTotalMutation) SetEndIndex(u uint64) {
+	m.end_index = &u
+	m.addend_index = nil
+}
+
+// EndIndex returns the value of the "end_index" field in the mutation.
+func (m *UsageTotalMutation) EndIndex() (r uint64, exists bool) {
+	v := m.end_index
+	if v == nil {
+		return
+	}
+	return *v, true
+}
+
+// OldEndIndex returns the old "end_index" field's value of the UsageTotal entity.
+// If the UsageTotal 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 *UsageTotalMutation) OldEndIndex(ctx context.Context) (v uint64, err error) {
+	if !m.op.Is(OpUpdateOne) {
+		return v, errors.New("OldEndIndex is only allowed on UpdateOne operations")
+	}
+	if m.id == nil || m.oldValue == nil {
+		return v, errors.New("OldEndIndex requires an ID field in the mutation")
+	}
+	oldValue, err := m.oldValue(ctx)
+	if err != nil {
+		return v, fmt.Errorf("querying old value for OldEndIndex: %w", err)
+	}
+	return oldValue.EndIndex, nil
+}
+
+// AddEndIndex adds u to the "end_index" field.
+func (m *UsageTotalMutation) AddEndIndex(u int64) {
+	if m.addend_index != nil {
+		*m.addend_index += u
+	} else {
+		m.addend_index = &u
+	}
+}
+
+// AddedEndIndex returns the value that was added to the "end_index" field in this mutation.
+func (m *UsageTotalMutation) AddedEndIndex() (r int64, exists bool) {
+	v := m.addend_index
+	if v == nil {
+		return
+	}
+	return *v, true
+}
+
+// ClearEndIndex clears the value of the "end_index" field.
+func (m *UsageTotalMutation) ClearEndIndex() {
+	m.end_index = nil
+	m.addend_index = nil
+	m.clearedFields[usagetotal.FieldEndIndex] = struct{}{}
+}
+
+// EndIndexCleared returns if the "end_index" field was cleared in this mutation.
+func (m *UsageTotalMutation) EndIndexCleared() bool {
+	_, ok := m.clearedFields[usagetotal.FieldEndIndex]
+	return ok
+}
+
+// ResetEndIndex resets all changes to the "end_index" field.
+func (m *UsageTotalMutation) ResetEndIndex() {
+	m.end_index = nil
+	m.addend_index = nil
+	delete(m.clearedFields, usagetotal.FieldEndIndex)
+}
+
+// SetOrganizationID sets the "organization_id" field.
+func (m *UsageTotalMutation) SetOrganizationID(u uint64) {
+	m.organization_id = &u
+	m.addorganization_id = nil
+}
+
+// OrganizationID returns the value of the "organization_id" field in the mutation.
+func (m *UsageTotalMutation) OrganizationID() (r uint64, exists bool) {
+	v := m.organization_id
+	if v == nil {
+		return
+	}
+	return *v, true
+}
+
+// OldOrganizationID returns the old "organization_id" field's value of the UsageTotal entity.
+// If the UsageTotal 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 *UsageTotalMutation) OldOrganizationID(ctx context.Context) (v uint64, err error) {
+	if !m.op.Is(OpUpdateOne) {
+		return v, errors.New("OldOrganizationID is only allowed on UpdateOne operations")
+	}
+	if m.id == nil || m.oldValue == nil {
+		return v, errors.New("OldOrganizationID requires an ID field in the mutation")
+	}
+	oldValue, err := m.oldValue(ctx)
+	if err != nil {
+		return v, fmt.Errorf("querying old value for OldOrganizationID: %w", err)
+	}
+	return oldValue.OrganizationID, nil
+}
+
+// AddOrganizationID adds u to the "organization_id" field.
+func (m *UsageTotalMutation) AddOrganizationID(u int64) {
+	if m.addorganization_id != nil {
+		*m.addorganization_id += u
+	} else {
+		m.addorganization_id = &u
+	}
+}
+
+// AddedOrganizationID returns the value that was added to the "organization_id" field in this mutation.
+func (m *UsageTotalMutation) AddedOrganizationID() (r int64, exists bool) {
+	v := m.addorganization_id
+	if v == nil {
+		return
+	}
+	return *v, true
+}
+
+// ClearOrganizationID clears the value of the "organization_id" field.
+func (m *UsageTotalMutation) ClearOrganizationID() {
+	m.organization_id = nil
+	m.addorganization_id = nil
+	m.clearedFields[usagetotal.FieldOrganizationID] = struct{}{}
+}
+
+// OrganizationIDCleared returns if the "organization_id" field was cleared in this mutation.
+func (m *UsageTotalMutation) OrganizationIDCleared() bool {
+	_, ok := m.clearedFields[usagetotal.FieldOrganizationID]
+	return ok
+}
+
+// ResetOrganizationID resets all changes to the "organization_id" field.
+func (m *UsageTotalMutation) ResetOrganizationID() {
+	m.organization_id = nil
+	m.addorganization_id = nil
+	delete(m.clearedFields, usagetotal.FieldOrganizationID)
+}
+
+// Where appends a list predicates to the UsageTotalMutation builder.
+func (m *UsageTotalMutation) Where(ps ...predicate.UsageTotal) {
+	m.predicates = append(m.predicates, ps...)
+}
+
+// WhereP appends storage-level predicates to the UsageTotalMutation builder. Using this method,
+// users can use type-assertion to append predicates that do not depend on any generated package.
+func (m *UsageTotalMutation) WhereP(ps ...func(*sql.Selector)) {
+	p := make([]predicate.UsageTotal, len(ps))
+	for i := range ps {
+		p[i] = ps[i]
+	}
+	m.Where(p...)
+}
+
+// Op returns the operation name.
+func (m *UsageTotalMutation) Op() Op {
+	return m.op
+}
+
+// SetOp allows setting the mutation operation.
+func (m *UsageTotalMutation) SetOp(op Op) {
+	m.op = op
+}
+
+// Type returns the node type of this mutation (UsageTotal).
+func (m *UsageTotalMutation) 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 *UsageTotalMutation) Fields() []string {
+	fields := make([]string, 0, 9)
+	if m.created_at != nil {
+		fields = append(fields, usagetotal.FieldCreatedAt)
+	}
+	if m.updated_at != nil {
+		fields = append(fields, usagetotal.FieldUpdatedAt)
+	}
+	if m.status != nil {
+		fields = append(fields, usagetotal.FieldStatus)
+	}
+	if m._type != nil {
+		fields = append(fields, usagetotal.FieldType)
+	}
+	if m.bot_id != nil {
+		fields = append(fields, usagetotal.FieldBotID)
+	}
+	if m.total_tokens != nil {
+		fields = append(fields, usagetotal.FieldTotalTokens)
+	}
+	if m.start_index != nil {
+		fields = append(fields, usagetotal.FieldStartIndex)
+	}
+	if m.end_index != nil {
+		fields = append(fields, usagetotal.FieldEndIndex)
+	}
+	if m.organization_id != nil {
+		fields = append(fields, usagetotal.FieldOrganizationID)
+	}
+	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 *UsageTotalMutation) Field(name string) (ent.Value, bool) {
+	switch name {
+	case usagetotal.FieldCreatedAt:
+		return m.CreatedAt()
+	case usagetotal.FieldUpdatedAt:
+		return m.UpdatedAt()
+	case usagetotal.FieldStatus:
+		return m.Status()
+	case usagetotal.FieldType:
+		return m.GetType()
+	case usagetotal.FieldBotID:
+		return m.BotID()
+	case usagetotal.FieldTotalTokens:
+		return m.TotalTokens()
+	case usagetotal.FieldStartIndex:
+		return m.StartIndex()
+	case usagetotal.FieldEndIndex:
+		return m.EndIndex()
+	case usagetotal.FieldOrganizationID:
+		return m.OrganizationID()
+	}
+	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 *UsageTotalMutation) OldField(ctx context.Context, name string) (ent.Value, error) {
+	switch name {
+	case usagetotal.FieldCreatedAt:
+		return m.OldCreatedAt(ctx)
+	case usagetotal.FieldUpdatedAt:
+		return m.OldUpdatedAt(ctx)
+	case usagetotal.FieldStatus:
+		return m.OldStatus(ctx)
+	case usagetotal.FieldType:
+		return m.OldType(ctx)
+	case usagetotal.FieldBotID:
+		return m.OldBotID(ctx)
+	case usagetotal.FieldTotalTokens:
+		return m.OldTotalTokens(ctx)
+	case usagetotal.FieldStartIndex:
+		return m.OldStartIndex(ctx)
+	case usagetotal.FieldEndIndex:
+		return m.OldEndIndex(ctx)
+	case usagetotal.FieldOrganizationID:
+		return m.OldOrganizationID(ctx)
+	}
+	return nil, fmt.Errorf("unknown UsageTotal 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 *UsageTotalMutation) SetField(name string, value ent.Value) error {
+	switch name {
+	case usagetotal.FieldCreatedAt:
+		v, ok := value.(time.Time)
+		if !ok {
+			return fmt.Errorf("unexpected type %T for field %s", value, name)
+		}
+		m.SetCreatedAt(v)
+		return nil
+	case usagetotal.FieldUpdatedAt:
+		v, ok := value.(time.Time)
+		if !ok {
+			return fmt.Errorf("unexpected type %T for field %s", value, name)
+		}
+		m.SetUpdatedAt(v)
+		return nil
+	case usagetotal.FieldStatus:
+		v, ok := value.(uint8)
+		if !ok {
+			return fmt.Errorf("unexpected type %T for field %s", value, name)
+		}
+		m.SetStatus(v)
+		return nil
+	case usagetotal.FieldType:
+		v, ok := value.(int)
+		if !ok {
+			return fmt.Errorf("unexpected type %T for field %s", value, name)
+		}
+		m.SetType(v)
+		return nil
+	case usagetotal.FieldBotID:
+		v, ok := value.(string)
+		if !ok {
+			return fmt.Errorf("unexpected type %T for field %s", value, name)
+		}
+		m.SetBotID(v)
+		return nil
+	case usagetotal.FieldTotalTokens:
+		v, ok := value.(uint64)
+		if !ok {
+			return fmt.Errorf("unexpected type %T for field %s", value, name)
+		}
+		m.SetTotalTokens(v)
+		return nil
+	case usagetotal.FieldStartIndex:
+		v, ok := value.(uint64)
+		if !ok {
+			return fmt.Errorf("unexpected type %T for field %s", value, name)
+		}
+		m.SetStartIndex(v)
+		return nil
+	case usagetotal.FieldEndIndex:
+		v, ok := value.(uint64)
+		if !ok {
+			return fmt.Errorf("unexpected type %T for field %s", value, name)
+		}
+		m.SetEndIndex(v)
+		return nil
+	case usagetotal.FieldOrganizationID:
+		v, ok := value.(uint64)
+		if !ok {
+			return fmt.Errorf("unexpected type %T for field %s", value, name)
+		}
+		m.SetOrganizationID(v)
+		return nil
+	}
+	return fmt.Errorf("unknown UsageTotal field %s", name)
+}
+
+// AddedFields returns all numeric fields that were incremented/decremented during
+// this mutation.
+func (m *UsageTotalMutation) AddedFields() []string {
+	var fields []string
+	if m.addstatus != nil {
+		fields = append(fields, usagetotal.FieldStatus)
+	}
+	if m.add_type != nil {
+		fields = append(fields, usagetotal.FieldType)
+	}
+	if m.addtotal_tokens != nil {
+		fields = append(fields, usagetotal.FieldTotalTokens)
+	}
+	if m.addstart_index != nil {
+		fields = append(fields, usagetotal.FieldStartIndex)
+	}
+	if m.addend_index != nil {
+		fields = append(fields, usagetotal.FieldEndIndex)
+	}
+	if m.addorganization_id != nil {
+		fields = append(fields, usagetotal.FieldOrganizationID)
+	}
+	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 *UsageTotalMutation) AddedField(name string) (ent.Value, bool) {
+	switch name {
+	case usagetotal.FieldStatus:
+		return m.AddedStatus()
+	case usagetotal.FieldType:
+		return m.AddedType()
+	case usagetotal.FieldTotalTokens:
+		return m.AddedTotalTokens()
+	case usagetotal.FieldStartIndex:
+		return m.AddedStartIndex()
+	case usagetotal.FieldEndIndex:
+		return m.AddedEndIndex()
+	case usagetotal.FieldOrganizationID:
+		return m.AddedOrganizationID()
+	}
+	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 *UsageTotalMutation) AddField(name string, value ent.Value) error {
+	switch name {
+	case usagetotal.FieldStatus:
+		v, ok := value.(int8)
+		if !ok {
+			return fmt.Errorf("unexpected type %T for field %s", value, name)
+		}
+		m.AddStatus(v)
+		return nil
+	case usagetotal.FieldType:
+		v, ok := value.(int)
+		if !ok {
+			return fmt.Errorf("unexpected type %T for field %s", value, name)
+		}
+		m.AddType(v)
+		return nil
+	case usagetotal.FieldTotalTokens:
+		v, ok := value.(int64)
+		if !ok {
+			return fmt.Errorf("unexpected type %T for field %s", value, name)
+		}
+		m.AddTotalTokens(v)
+		return nil
+	case usagetotal.FieldStartIndex:
+		v, ok := value.(int64)
+		if !ok {
+			return fmt.Errorf("unexpected type %T for field %s", value, name)
+		}
+		m.AddStartIndex(v)
+		return nil
+	case usagetotal.FieldEndIndex:
+		v, ok := value.(int64)
+		if !ok {
+			return fmt.Errorf("unexpected type %T for field %s", value, name)
+		}
+		m.AddEndIndex(v)
+		return nil
+	case usagetotal.FieldOrganizationID:
+		v, ok := value.(int64)
+		if !ok {
+			return fmt.Errorf("unexpected type %T for field %s", value, name)
+		}
+		m.AddOrganizationID(v)
+		return nil
+	}
+	return fmt.Errorf("unknown UsageTotal numeric field %s", name)
+}
+
+// ClearedFields returns all nullable fields that were cleared during this
+// mutation.
+func (m *UsageTotalMutation) ClearedFields() []string {
+	var fields []string
+	if m.FieldCleared(usagetotal.FieldStatus) {
+		fields = append(fields, usagetotal.FieldStatus)
+	}
+	if m.FieldCleared(usagetotal.FieldType) {
+		fields = append(fields, usagetotal.FieldType)
+	}
+	if m.FieldCleared(usagetotal.FieldTotalTokens) {
+		fields = append(fields, usagetotal.FieldTotalTokens)
+	}
+	if m.FieldCleared(usagetotal.FieldStartIndex) {
+		fields = append(fields, usagetotal.FieldStartIndex)
+	}
+	if m.FieldCleared(usagetotal.FieldEndIndex) {
+		fields = append(fields, usagetotal.FieldEndIndex)
+	}
+	if m.FieldCleared(usagetotal.FieldOrganizationID) {
+		fields = append(fields, usagetotal.FieldOrganizationID)
+	}
+	return fields
+}
+
+// FieldCleared returns a boolean indicating if a field with the given name was
+// cleared in this mutation.
+func (m *UsageTotalMutation) 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 *UsageTotalMutation) ClearField(name string) error {
+	switch name {
+	case usagetotal.FieldStatus:
+		m.ClearStatus()
+		return nil
+	case usagetotal.FieldType:
+		m.ClearType()
+		return nil
+	case usagetotal.FieldTotalTokens:
+		m.ClearTotalTokens()
+		return nil
+	case usagetotal.FieldStartIndex:
+		m.ClearStartIndex()
+		return nil
+	case usagetotal.FieldEndIndex:
+		m.ClearEndIndex()
+		return nil
+	case usagetotal.FieldOrganizationID:
+		m.ClearOrganizationID()
+		return nil
+	}
+	return fmt.Errorf("unknown UsageTotal 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 *UsageTotalMutation) ResetField(name string) error {
+	switch name {
+	case usagetotal.FieldCreatedAt:
+		m.ResetCreatedAt()
+		return nil
+	case usagetotal.FieldUpdatedAt:
+		m.ResetUpdatedAt()
+		return nil
+	case usagetotal.FieldStatus:
+		m.ResetStatus()
+		return nil
+	case usagetotal.FieldType:
+		m.ResetType()
+		return nil
+	case usagetotal.FieldBotID:
+		m.ResetBotID()
+		return nil
+	case usagetotal.FieldTotalTokens:
+		m.ResetTotalTokens()
+		return nil
+	case usagetotal.FieldStartIndex:
+		m.ResetStartIndex()
+		return nil
+	case usagetotal.FieldEndIndex:
+		m.ResetEndIndex()
+		return nil
+	case usagetotal.FieldOrganizationID:
+		m.ResetOrganizationID()
+		return nil
+	}
+	return fmt.Errorf("unknown UsageTotal field %s", name)
+}
+
+// AddedEdges returns all edge names that were set/added in this mutation.
+func (m *UsageTotalMutation) AddedEdges() []string {
+	edges := make([]string, 0, 0)
+	return edges
+}
+
+// AddedIDs returns all IDs (to other nodes) that were added for the given edge
+// name in this mutation.
+func (m *UsageTotalMutation) AddedIDs(name string) []ent.Value {
+	return nil
+}
+
+// RemovedEdges returns all edge names that were removed in this mutation.
+func (m *UsageTotalMutation) RemovedEdges() []string {
+	edges := make([]string, 0, 0)
+	return edges
+}
+
+// RemovedIDs returns all IDs (to other nodes) that were removed for the edge with
+// the given name in this mutation.
+func (m *UsageTotalMutation) RemovedIDs(name string) []ent.Value {
+	return nil
+}
+
+// ClearedEdges returns all edge names that were cleared in this mutation.
+func (m *UsageTotalMutation) ClearedEdges() []string {
+	edges := make([]string, 0, 0)
+	return edges
+}
+
+// EdgeCleared returns a boolean which indicates if the edge with the given name
+// was cleared in this mutation.
+func (m *UsageTotalMutation) EdgeCleared(name string) bool {
+	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 *UsageTotalMutation) ClearEdge(name string) error {
+	return fmt.Errorf("unknown UsageTotal 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 *UsageTotalMutation) ResetEdge(name string) error {
+	return fmt.Errorf("unknown UsageTotal edge %s", name)
+}
+
 // WorkExperienceMutation represents an operation that mutates the WorkExperience nodes in the graph.
 type WorkExperienceMutation struct {
 	config

+ 164 - 0
ent/pagination.go

@@ -26,6 +26,8 @@ import (
 	"wechat-api/ent/soptask"
 	"wechat-api/ent/token"
 	"wechat-api/ent/tutorial"
+	"wechat-api/ent/usagedetail"
+	"wechat-api/ent/usagetotal"
 	"wechat-api/ent/workexperience"
 	"wechat-api/ent/wx"
 	"wechat-api/ent/wxcard"
@@ -1780,6 +1782,168 @@ func (t *TutorialQuery) Page(
 	return ret, nil
 }
 
+type UsageDetailPager struct {
+	Order  usagedetail.OrderOption
+	Filter func(*UsageDetailQuery) (*UsageDetailQuery, error)
+}
+
+// UsageDetailPaginateOption enables pagination customization.
+type UsageDetailPaginateOption func(*UsageDetailPager)
+
+// DefaultUsageDetailOrder is the default ordering of UsageDetail.
+var DefaultUsageDetailOrder = Desc(usagedetail.FieldID)
+
+func newUsageDetailPager(opts []UsageDetailPaginateOption) (*UsageDetailPager, error) {
+	pager := &UsageDetailPager{}
+	for _, opt := range opts {
+		opt(pager)
+	}
+	if pager.Order == nil {
+		pager.Order = DefaultUsageDetailOrder
+	}
+	return pager, nil
+}
+
+func (p *UsageDetailPager) ApplyFilter(query *UsageDetailQuery) (*UsageDetailQuery, error) {
+	if p.Filter != nil {
+		return p.Filter(query)
+	}
+	return query, nil
+}
+
+// UsageDetailPageList is UsageDetail PageList result.
+type UsageDetailPageList struct {
+	List        []*UsageDetail `json:"list"`
+	PageDetails *PageDetails   `json:"pageDetails"`
+}
+
+func (ud *UsageDetailQuery) Page(
+	ctx context.Context, pageNum uint64, pageSize uint64, opts ...UsageDetailPaginateOption,
+) (*UsageDetailPageList, error) {
+
+	pager, err := newUsageDetailPager(opts)
+	if err != nil {
+		return nil, err
+	}
+
+	if ud, err = pager.ApplyFilter(ud); err != nil {
+		return nil, err
+	}
+
+	ret := &UsageDetailPageList{}
+
+	ret.PageDetails = &PageDetails{
+		Page: pageNum,
+		Size: pageSize,
+	}
+
+	query := ud.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 {
+		ud = ud.Order(pager.Order)
+	} else {
+		ud = ud.Order(DefaultUsageDetailOrder)
+	}
+
+	ud = ud.Offset(int((pageNum - 1) * pageSize)).Limit(int(pageSize))
+	list, err := ud.All(ctx)
+	if err != nil {
+		return nil, err
+	}
+	ret.List = list
+
+	return ret, nil
+}
+
+type UsageTotalPager struct {
+	Order  usagetotal.OrderOption
+	Filter func(*UsageTotalQuery) (*UsageTotalQuery, error)
+}
+
+// UsageTotalPaginateOption enables pagination customization.
+type UsageTotalPaginateOption func(*UsageTotalPager)
+
+// DefaultUsageTotalOrder is the default ordering of UsageTotal.
+var DefaultUsageTotalOrder = Desc(usagetotal.FieldID)
+
+func newUsageTotalPager(opts []UsageTotalPaginateOption) (*UsageTotalPager, error) {
+	pager := &UsageTotalPager{}
+	for _, opt := range opts {
+		opt(pager)
+	}
+	if pager.Order == nil {
+		pager.Order = DefaultUsageTotalOrder
+	}
+	return pager, nil
+}
+
+func (p *UsageTotalPager) ApplyFilter(query *UsageTotalQuery) (*UsageTotalQuery, error) {
+	if p.Filter != nil {
+		return p.Filter(query)
+	}
+	return query, nil
+}
+
+// UsageTotalPageList is UsageTotal PageList result.
+type UsageTotalPageList struct {
+	List        []*UsageTotal `json:"list"`
+	PageDetails *PageDetails  `json:"pageDetails"`
+}
+
+func (ut *UsageTotalQuery) Page(
+	ctx context.Context, pageNum uint64, pageSize uint64, opts ...UsageTotalPaginateOption,
+) (*UsageTotalPageList, error) {
+
+	pager, err := newUsageTotalPager(opts)
+	if err != nil {
+		return nil, err
+	}
+
+	if ut, err = pager.ApplyFilter(ut); err != nil {
+		return nil, err
+	}
+
+	ret := &UsageTotalPageList{}
+
+	ret.PageDetails = &PageDetails{
+		Page: pageNum,
+		Size: pageSize,
+	}
+
+	query := ut.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 {
+		ut = ut.Order(pager.Order)
+	} else {
+		ut = ut.Order(DefaultUsageTotalOrder)
+	}
+
+	ut = ut.Offset(int((pageNum - 1) * pageSize)).Limit(int(pageSize))
+	list, err := ut.All(ctx)
+	if err != nil {
+		return nil, err
+	}
+	ret.List = list
+
+	return ret, nil
+}
+
 type WorkExperiencePager struct {
 	Order  workexperience.OrderOption
 	Filter func(*WorkExperienceQuery) (*WorkExperienceQuery, error)

+ 6 - 0
ent/predicate/predicate.go

@@ -69,6 +69,12 @@ type Token func(*sql.Selector)
 // Tutorial is the predicate function for tutorial builders.
 type Tutorial func(*sql.Selector)
 
+// UsageDetail is the predicate function for usagedetail builders.
+type UsageDetail func(*sql.Selector)
+
+// UsageTotal is the predicate function for usagetotal builders.
+type UsageTotal func(*sql.Selector)
+
 // WorkExperience is the predicate function for workexperience builders.
 type WorkExperience func(*sql.Selector)
 

+ 112 - 0
ent/runtime/runtime.go

@@ -26,6 +26,8 @@ import (
 	"wechat-api/ent/soptask"
 	"wechat-api/ent/token"
 	"wechat-api/ent/tutorial"
+	"wechat-api/ent/usagedetail"
+	"wechat-api/ent/usagetotal"
 	"wechat-api/ent/workexperience"
 	"wechat-api/ent/wx"
 	"wechat-api/ent/wxcard"
@@ -898,6 +900,116 @@ func init() {
 	tutorialDescOrganizationID := tutorialFields[4].Descriptor()
 	// tutorial.OrganizationIDValidator is a validator for the "organization_id" field. It is called by the builders before save.
 	tutorial.OrganizationIDValidator = tutorialDescOrganizationID.Validators[0].(func(uint64) error)
+	usagedetailMixin := schema.UsageDetail{}.Mixin()
+	usagedetailMixinFields0 := usagedetailMixin[0].Fields()
+	_ = usagedetailMixinFields0
+	usagedetailMixinFields1 := usagedetailMixin[1].Fields()
+	_ = usagedetailMixinFields1
+	usagedetailFields := schema.UsageDetail{}.Fields()
+	_ = usagedetailFields
+	// usagedetailDescCreatedAt is the schema descriptor for created_at field.
+	usagedetailDescCreatedAt := usagedetailMixinFields0[1].Descriptor()
+	// usagedetail.DefaultCreatedAt holds the default value on creation for the created_at field.
+	usagedetail.DefaultCreatedAt = usagedetailDescCreatedAt.Default.(func() time.Time)
+	// usagedetailDescUpdatedAt is the schema descriptor for updated_at field.
+	usagedetailDescUpdatedAt := usagedetailMixinFields0[2].Descriptor()
+	// usagedetail.DefaultUpdatedAt holds the default value on creation for the updated_at field.
+	usagedetail.DefaultUpdatedAt = usagedetailDescUpdatedAt.Default.(func() time.Time)
+	// usagedetail.UpdateDefaultUpdatedAt holds the default value on update for the updated_at field.
+	usagedetail.UpdateDefaultUpdatedAt = usagedetailDescUpdatedAt.UpdateDefault.(func() time.Time)
+	// usagedetailDescStatus is the schema descriptor for status field.
+	usagedetailDescStatus := usagedetailMixinFields1[0].Descriptor()
+	// usagedetail.DefaultStatus holds the default value on creation for the status field.
+	usagedetail.DefaultStatus = usagedetailDescStatus.Default.(uint8)
+	// usagedetailDescType is the schema descriptor for type field.
+	usagedetailDescType := usagedetailFields[0].Descriptor()
+	// usagedetail.DefaultType holds the default value on creation for the type field.
+	usagedetail.DefaultType = usagedetailDescType.Default.(int)
+	// usagedetailDescBotID is the schema descriptor for bot_id field.
+	usagedetailDescBotID := usagedetailFields[1].Descriptor()
+	// usagedetail.DefaultBotID holds the default value on creation for the bot_id field.
+	usagedetail.DefaultBotID = usagedetailDescBotID.Default.(string)
+	// usagedetailDescReceiverID is the schema descriptor for receiver_id field.
+	usagedetailDescReceiverID := usagedetailFields[2].Descriptor()
+	// usagedetail.DefaultReceiverID holds the default value on creation for the receiver_id field.
+	usagedetail.DefaultReceiverID = usagedetailDescReceiverID.Default.(string)
+	// usagedetailDescApp is the schema descriptor for app field.
+	usagedetailDescApp := usagedetailFields[3].Descriptor()
+	// usagedetail.DefaultApp holds the default value on creation for the app field.
+	usagedetail.DefaultApp = usagedetailDescApp.Default.(int)
+	// usagedetailDescSessionID is the schema descriptor for session_id field.
+	usagedetailDescSessionID := usagedetailFields[4].Descriptor()
+	// usagedetail.DefaultSessionID holds the default value on creation for the session_id field.
+	usagedetail.DefaultSessionID = usagedetailDescSessionID.Default.(uint64)
+	// usagedetailDescRequest is the schema descriptor for request field.
+	usagedetailDescRequest := usagedetailFields[5].Descriptor()
+	// usagedetail.DefaultRequest holds the default value on creation for the request field.
+	usagedetail.DefaultRequest = usagedetailDescRequest.Default.(string)
+	// usagedetailDescResponse is the schema descriptor for response field.
+	usagedetailDescResponse := usagedetailFields[6].Descriptor()
+	// usagedetail.DefaultResponse holds the default value on creation for the response field.
+	usagedetail.DefaultResponse = usagedetailDescResponse.Default.(string)
+	// usagedetailDescTotalTokens is the schema descriptor for total_tokens field.
+	usagedetailDescTotalTokens := usagedetailFields[7].Descriptor()
+	// usagedetail.DefaultTotalTokens holds the default value on creation for the total_tokens field.
+	usagedetail.DefaultTotalTokens = usagedetailDescTotalTokens.Default.(uint64)
+	// usagedetailDescPromptTokens is the schema descriptor for prompt_tokens field.
+	usagedetailDescPromptTokens := usagedetailFields[8].Descriptor()
+	// usagedetail.DefaultPromptTokens holds the default value on creation for the prompt_tokens field.
+	usagedetail.DefaultPromptTokens = usagedetailDescPromptTokens.Default.(uint64)
+	// usagedetailDescCompletionTokens is the schema descriptor for completion_tokens field.
+	usagedetailDescCompletionTokens := usagedetailFields[9].Descriptor()
+	// usagedetail.DefaultCompletionTokens holds the default value on creation for the completion_tokens field.
+	usagedetail.DefaultCompletionTokens = usagedetailDescCompletionTokens.Default.(uint64)
+	// usagedetailDescOrganizationID is the schema descriptor for organization_id field.
+	usagedetailDescOrganizationID := usagedetailFields[10].Descriptor()
+	// usagedetail.DefaultOrganizationID holds the default value on creation for the organization_id field.
+	usagedetail.DefaultOrganizationID = usagedetailDescOrganizationID.Default.(uint64)
+	usagetotalMixin := schema.UsageTotal{}.Mixin()
+	usagetotalMixinFields0 := usagetotalMixin[0].Fields()
+	_ = usagetotalMixinFields0
+	usagetotalMixinFields1 := usagetotalMixin[1].Fields()
+	_ = usagetotalMixinFields1
+	usagetotalFields := schema.UsageTotal{}.Fields()
+	_ = usagetotalFields
+	// usagetotalDescCreatedAt is the schema descriptor for created_at field.
+	usagetotalDescCreatedAt := usagetotalMixinFields0[1].Descriptor()
+	// usagetotal.DefaultCreatedAt holds the default value on creation for the created_at field.
+	usagetotal.DefaultCreatedAt = usagetotalDescCreatedAt.Default.(func() time.Time)
+	// usagetotalDescUpdatedAt is the schema descriptor for updated_at field.
+	usagetotalDescUpdatedAt := usagetotalMixinFields0[2].Descriptor()
+	// usagetotal.DefaultUpdatedAt holds the default value on creation for the updated_at field.
+	usagetotal.DefaultUpdatedAt = usagetotalDescUpdatedAt.Default.(func() time.Time)
+	// usagetotal.UpdateDefaultUpdatedAt holds the default value on update for the updated_at field.
+	usagetotal.UpdateDefaultUpdatedAt = usagetotalDescUpdatedAt.UpdateDefault.(func() time.Time)
+	// usagetotalDescStatus is the schema descriptor for status field.
+	usagetotalDescStatus := usagetotalMixinFields1[0].Descriptor()
+	// usagetotal.DefaultStatus holds the default value on creation for the status field.
+	usagetotal.DefaultStatus = usagetotalDescStatus.Default.(uint8)
+	// usagetotalDescType is the schema descriptor for type field.
+	usagetotalDescType := usagetotalFields[0].Descriptor()
+	// usagetotal.DefaultType holds the default value on creation for the type field.
+	usagetotal.DefaultType = usagetotalDescType.Default.(int)
+	// usagetotalDescBotID is the schema descriptor for bot_id field.
+	usagetotalDescBotID := usagetotalFields[1].Descriptor()
+	// usagetotal.DefaultBotID holds the default value on creation for the bot_id field.
+	usagetotal.DefaultBotID = usagetotalDescBotID.Default.(string)
+	// usagetotalDescTotalTokens is the schema descriptor for total_tokens field.
+	usagetotalDescTotalTokens := usagetotalFields[2].Descriptor()
+	// usagetotal.DefaultTotalTokens holds the default value on creation for the total_tokens field.
+	usagetotal.DefaultTotalTokens = usagetotalDescTotalTokens.Default.(uint64)
+	// usagetotalDescStartIndex is the schema descriptor for start_index field.
+	usagetotalDescStartIndex := usagetotalFields[3].Descriptor()
+	// usagetotal.DefaultStartIndex holds the default value on creation for the start_index field.
+	usagetotal.DefaultStartIndex = usagetotalDescStartIndex.Default.(uint64)
+	// usagetotalDescEndIndex is the schema descriptor for end_index field.
+	usagetotalDescEndIndex := usagetotalFields[4].Descriptor()
+	// usagetotal.DefaultEndIndex holds the default value on creation for the end_index field.
+	usagetotal.DefaultEndIndex = usagetotalDescEndIndex.Default.(uint64)
+	// usagetotalDescOrganizationID is the schema descriptor for organization_id field.
+	usagetotalDescOrganizationID := usagetotalFields[5].Descriptor()
+	// usagetotal.DefaultOrganizationID holds the default value on creation for the organization_id field.
+	usagetotal.DefaultOrganizationID = usagetotalDescOrganizationID.Default.(uint64)
 	workexperienceMixin := schema.WorkExperience{}.Mixin()
 	workexperienceMixinHooks1 := workexperienceMixin[1].Hooks()
 	workexperience.Hooks[0] = workexperienceMixinHooks1[0]

+ 75 - 0
ent/schema/usage_detail.go

@@ -0,0 +1,75 @@
+package schema
+
+import (
+	"entgo.io/ent"
+	"entgo.io/ent/dialect/entsql"
+	"entgo.io/ent/schema"
+	"entgo.io/ent/schema/field"
+	"entgo.io/ent/schema/index"
+	"github.com/suyuan32/simple-admin-common/orm/ent/mixins"
+)
+
+type UsageDetail struct {
+	ent.Schema
+}
+
+func (UsageDetail) Fields() []ent.Field {
+	return []ent.Field{
+		field.Int("type").Optional().Default(1).
+			Annotations(entsql.WithComments(true)).
+			Comment("1 微信 2 名片"),
+		field.String("bot_id").Default("").
+			Annotations(entsql.WithComments(true)).
+			Comment("微信或名片id"),
+		field.String("receiver_id").Default("").
+			Annotations(entsql.WithComments(true)).
+			Comment("微信id或open_id"),
+		field.Int("app").Optional().Default(1).
+			Annotations(entsql.WithComments(true)).
+			Comment("1 cow-basic 2 cow-agent 3 cow-sop 4 mp-card 5 mp-employee"),
+		field.Uint64("session_id").Optional().Default(1).
+			Comment("名片会话id").
+			Annotations(entsql.WithComments(true)),
+		field.String("request").Default("").
+			Annotations(entsql.WithComments(true)).
+			Comment("请求内容"),
+		field.String("response").Default("").
+			Annotations(entsql.WithComments(true)).
+			Comment("响应内容"),
+		field.Uint64("total_tokens").Optional().Default(0).
+			Annotations(entsql.WithComments(true)).
+			Comment("使用token总数"),
+		field.Uint64("prompt_tokens").Optional().Default(0).
+			Annotations(entsql.WithComments(true)).
+			Comment("请求token数"),
+		field.Uint64("completion_tokens").Optional().Default(0).
+			Annotations(entsql.WithComments(true)).
+			Comment("响应token数"),
+		field.Uint64("organization_id").Optional().Default(1).
+			Comment("机构 ID").
+			Annotations(entsql.WithComments(true)),
+	}
+}
+
+func (UsageDetail) Mixin() []ent.Mixin {
+	return []ent.Mixin{
+		mixins.IDMixin{},
+		mixins.StatusMixin{},
+	}
+}
+
+func (UsageDetail) Indexes() []ent.Index {
+	return []ent.Index{
+		index.Fields("bot_id"),
+		index.Fields("organization_id"),
+	}
+}
+
+func (UsageDetail) Edges() []ent.Edge { return []ent.Edge{} }
+
+func (UsageDetail) Annotations() []schema.Annotation {
+	return []schema.Annotation{
+		entsql.WithComments(true),
+		entsql.Annotation{Table: "usage_detail"},
+	}
+}

+ 60 - 0
ent/schema/usage_total.go

@@ -0,0 +1,60 @@
+package schema
+
+import (
+	"entgo.io/ent"
+	"entgo.io/ent/dialect/entsql"
+	"entgo.io/ent/schema"
+	"entgo.io/ent/schema/field"
+	"entgo.io/ent/schema/index"
+	"github.com/suyuan32/simple-admin-common/orm/ent/mixins"
+)
+
+type UsageTotal struct {
+	ent.Schema
+}
+
+func (UsageTotal) Fields() []ent.Field {
+	return []ent.Field{
+		field.Int("type").Optional().Default(1).
+			Annotations(entsql.WithComments(true)).
+			Comment("1 微信 2 名片"),
+		field.String("bot_id").Default("").
+			Annotations(entsql.WithComments(true)).
+			Comment("微信或名片id"),
+		field.Uint64("total_tokens").Optional().Default(0).
+			Annotations(entsql.WithComments(true)).
+			Comment("使用token总数"),
+		field.Uint64("start_index").Optional().Default(0).
+			Annotations(entsql.WithComments(true)).
+			Comment("重制后的起始usage_detail 索引"),
+		field.Uint64("end_index").Optional().Default(0).
+			Annotations(entsql.WithComments(true)).
+			Comment("usage_detail 索引"),
+		field.Uint64("organization_id").Optional().Default(1).
+			Comment("机构 ID").
+			Annotations(entsql.WithComments(true)),
+	}
+}
+
+func (UsageTotal) Mixin() []ent.Mixin {
+	return []ent.Mixin{
+		mixins.IDMixin{},
+		mixins.StatusMixin{},
+	}
+}
+
+func (UsageTotal) Indexes() []ent.Index {
+	return []ent.Index{
+		index.Fields("bot_id"),
+		index.Fields("organization_id"),
+	}
+}
+
+func (UsageTotal) Edges() []ent.Edge { return []ent.Edge{} }
+
+func (UsageTotal) Annotations() []schema.Annotation {
+	return []schema.Annotation{
+		entsql.WithComments(true),
+		entsql.Annotation{Table: "usage_total"},
+	}
+}

+ 504 - 0
ent/set_not_nil.go

@@ -5168,6 +5168,510 @@ func (t *TutorialCreate) SetNotNilOrganizationID(value *uint64) *TutorialCreate
 }
 
 // set field if value's pointer is not nil.
+func (ud *UsageDetailUpdate) SetNotNilUpdatedAt(value *time.Time) *UsageDetailUpdate {
+	if value != nil {
+		return ud.SetUpdatedAt(*value)
+	}
+	return ud
+}
+
+// set field if value's pointer is not nil.
+func (ud *UsageDetailUpdateOne) SetNotNilUpdatedAt(value *time.Time) *UsageDetailUpdateOne {
+	if value != nil {
+		return ud.SetUpdatedAt(*value)
+	}
+	return ud
+}
+
+// set field if value's pointer is not nil.
+func (ud *UsageDetailCreate) SetNotNilUpdatedAt(value *time.Time) *UsageDetailCreate {
+	if value != nil {
+		return ud.SetUpdatedAt(*value)
+	}
+	return ud
+}
+
+// set field if value's pointer is not nil.
+func (ud *UsageDetailUpdate) SetNotNilStatus(value *uint8) *UsageDetailUpdate {
+	if value != nil {
+		return ud.SetStatus(*value)
+	}
+	return ud
+}
+
+// set field if value's pointer is not nil.
+func (ud *UsageDetailUpdateOne) SetNotNilStatus(value *uint8) *UsageDetailUpdateOne {
+	if value != nil {
+		return ud.SetStatus(*value)
+	}
+	return ud
+}
+
+// set field if value's pointer is not nil.
+func (ud *UsageDetailCreate) SetNotNilStatus(value *uint8) *UsageDetailCreate {
+	if value != nil {
+		return ud.SetStatus(*value)
+	}
+	return ud
+}
+
+// set field if value's pointer is not nil.
+func (ud *UsageDetailUpdate) SetNotNilType(value *int) *UsageDetailUpdate {
+	if value != nil {
+		return ud.SetType(*value)
+	}
+	return ud
+}
+
+// set field if value's pointer is not nil.
+func (ud *UsageDetailUpdateOne) SetNotNilType(value *int) *UsageDetailUpdateOne {
+	if value != nil {
+		return ud.SetType(*value)
+	}
+	return ud
+}
+
+// set field if value's pointer is not nil.
+func (ud *UsageDetailCreate) SetNotNilType(value *int) *UsageDetailCreate {
+	if value != nil {
+		return ud.SetType(*value)
+	}
+	return ud
+}
+
+// set field if value's pointer is not nil.
+func (ud *UsageDetailUpdate) SetNotNilBotID(value *string) *UsageDetailUpdate {
+	if value != nil {
+		return ud.SetBotID(*value)
+	}
+	return ud
+}
+
+// set field if value's pointer is not nil.
+func (ud *UsageDetailUpdateOne) SetNotNilBotID(value *string) *UsageDetailUpdateOne {
+	if value != nil {
+		return ud.SetBotID(*value)
+	}
+	return ud
+}
+
+// set field if value's pointer is not nil.
+func (ud *UsageDetailCreate) SetNotNilBotID(value *string) *UsageDetailCreate {
+	if value != nil {
+		return ud.SetBotID(*value)
+	}
+	return ud
+}
+
+// set field if value's pointer is not nil.
+func (ud *UsageDetailUpdate) SetNotNilReceiverID(value *string) *UsageDetailUpdate {
+	if value != nil {
+		return ud.SetReceiverID(*value)
+	}
+	return ud
+}
+
+// set field if value's pointer is not nil.
+func (ud *UsageDetailUpdateOne) SetNotNilReceiverID(value *string) *UsageDetailUpdateOne {
+	if value != nil {
+		return ud.SetReceiverID(*value)
+	}
+	return ud
+}
+
+// set field if value's pointer is not nil.
+func (ud *UsageDetailCreate) SetNotNilReceiverID(value *string) *UsageDetailCreate {
+	if value != nil {
+		return ud.SetReceiverID(*value)
+	}
+	return ud
+}
+
+// set field if value's pointer is not nil.
+func (ud *UsageDetailUpdate) SetNotNilApp(value *int) *UsageDetailUpdate {
+	if value != nil {
+		return ud.SetApp(*value)
+	}
+	return ud
+}
+
+// set field if value's pointer is not nil.
+func (ud *UsageDetailUpdateOne) SetNotNilApp(value *int) *UsageDetailUpdateOne {
+	if value != nil {
+		return ud.SetApp(*value)
+	}
+	return ud
+}
+
+// set field if value's pointer is not nil.
+func (ud *UsageDetailCreate) SetNotNilApp(value *int) *UsageDetailCreate {
+	if value != nil {
+		return ud.SetApp(*value)
+	}
+	return ud
+}
+
+// set field if value's pointer is not nil.
+func (ud *UsageDetailUpdate) SetNotNilSessionID(value *uint64) *UsageDetailUpdate {
+	if value != nil {
+		return ud.SetSessionID(*value)
+	}
+	return ud
+}
+
+// set field if value's pointer is not nil.
+func (ud *UsageDetailUpdateOne) SetNotNilSessionID(value *uint64) *UsageDetailUpdateOne {
+	if value != nil {
+		return ud.SetSessionID(*value)
+	}
+	return ud
+}
+
+// set field if value's pointer is not nil.
+func (ud *UsageDetailCreate) SetNotNilSessionID(value *uint64) *UsageDetailCreate {
+	if value != nil {
+		return ud.SetSessionID(*value)
+	}
+	return ud
+}
+
+// set field if value's pointer is not nil.
+func (ud *UsageDetailUpdate) SetNotNilRequest(value *string) *UsageDetailUpdate {
+	if value != nil {
+		return ud.SetRequest(*value)
+	}
+	return ud
+}
+
+// set field if value's pointer is not nil.
+func (ud *UsageDetailUpdateOne) SetNotNilRequest(value *string) *UsageDetailUpdateOne {
+	if value != nil {
+		return ud.SetRequest(*value)
+	}
+	return ud
+}
+
+// set field if value's pointer is not nil.
+func (ud *UsageDetailCreate) SetNotNilRequest(value *string) *UsageDetailCreate {
+	if value != nil {
+		return ud.SetRequest(*value)
+	}
+	return ud
+}
+
+// set field if value's pointer is not nil.
+func (ud *UsageDetailUpdate) SetNotNilResponse(value *string) *UsageDetailUpdate {
+	if value != nil {
+		return ud.SetResponse(*value)
+	}
+	return ud
+}
+
+// set field if value's pointer is not nil.
+func (ud *UsageDetailUpdateOne) SetNotNilResponse(value *string) *UsageDetailUpdateOne {
+	if value != nil {
+		return ud.SetResponse(*value)
+	}
+	return ud
+}
+
+// set field if value's pointer is not nil.
+func (ud *UsageDetailCreate) SetNotNilResponse(value *string) *UsageDetailCreate {
+	if value != nil {
+		return ud.SetResponse(*value)
+	}
+	return ud
+}
+
+// set field if value's pointer is not nil.
+func (ud *UsageDetailUpdate) SetNotNilTotalTokens(value *uint64) *UsageDetailUpdate {
+	if value != nil {
+		return ud.SetTotalTokens(*value)
+	}
+	return ud
+}
+
+// set field if value's pointer is not nil.
+func (ud *UsageDetailUpdateOne) SetNotNilTotalTokens(value *uint64) *UsageDetailUpdateOne {
+	if value != nil {
+		return ud.SetTotalTokens(*value)
+	}
+	return ud
+}
+
+// set field if value's pointer is not nil.
+func (ud *UsageDetailCreate) SetNotNilTotalTokens(value *uint64) *UsageDetailCreate {
+	if value != nil {
+		return ud.SetTotalTokens(*value)
+	}
+	return ud
+}
+
+// set field if value's pointer is not nil.
+func (ud *UsageDetailUpdate) SetNotNilPromptTokens(value *uint64) *UsageDetailUpdate {
+	if value != nil {
+		return ud.SetPromptTokens(*value)
+	}
+	return ud
+}
+
+// set field if value's pointer is not nil.
+func (ud *UsageDetailUpdateOne) SetNotNilPromptTokens(value *uint64) *UsageDetailUpdateOne {
+	if value != nil {
+		return ud.SetPromptTokens(*value)
+	}
+	return ud
+}
+
+// set field if value's pointer is not nil.
+func (ud *UsageDetailCreate) SetNotNilPromptTokens(value *uint64) *UsageDetailCreate {
+	if value != nil {
+		return ud.SetPromptTokens(*value)
+	}
+	return ud
+}
+
+// set field if value's pointer is not nil.
+func (ud *UsageDetailUpdate) SetNotNilCompletionTokens(value *uint64) *UsageDetailUpdate {
+	if value != nil {
+		return ud.SetCompletionTokens(*value)
+	}
+	return ud
+}
+
+// set field if value's pointer is not nil.
+func (ud *UsageDetailUpdateOne) SetNotNilCompletionTokens(value *uint64) *UsageDetailUpdateOne {
+	if value != nil {
+		return ud.SetCompletionTokens(*value)
+	}
+	return ud
+}
+
+// set field if value's pointer is not nil.
+func (ud *UsageDetailCreate) SetNotNilCompletionTokens(value *uint64) *UsageDetailCreate {
+	if value != nil {
+		return ud.SetCompletionTokens(*value)
+	}
+	return ud
+}
+
+// set field if value's pointer is not nil.
+func (ud *UsageDetailUpdate) SetNotNilOrganizationID(value *uint64) *UsageDetailUpdate {
+	if value != nil {
+		return ud.SetOrganizationID(*value)
+	}
+	return ud
+}
+
+// set field if value's pointer is not nil.
+func (ud *UsageDetailUpdateOne) SetNotNilOrganizationID(value *uint64) *UsageDetailUpdateOne {
+	if value != nil {
+		return ud.SetOrganizationID(*value)
+	}
+	return ud
+}
+
+// set field if value's pointer is not nil.
+func (ud *UsageDetailCreate) SetNotNilOrganizationID(value *uint64) *UsageDetailCreate {
+	if value != nil {
+		return ud.SetOrganizationID(*value)
+	}
+	return ud
+}
+
+// set field if value's pointer is not nil.
+func (ut *UsageTotalUpdate) SetNotNilUpdatedAt(value *time.Time) *UsageTotalUpdate {
+	if value != nil {
+		return ut.SetUpdatedAt(*value)
+	}
+	return ut
+}
+
+// set field if value's pointer is not nil.
+func (ut *UsageTotalUpdateOne) SetNotNilUpdatedAt(value *time.Time) *UsageTotalUpdateOne {
+	if value != nil {
+		return ut.SetUpdatedAt(*value)
+	}
+	return ut
+}
+
+// set field if value's pointer is not nil.
+func (ut *UsageTotalCreate) SetNotNilUpdatedAt(value *time.Time) *UsageTotalCreate {
+	if value != nil {
+		return ut.SetUpdatedAt(*value)
+	}
+	return ut
+}
+
+// set field if value's pointer is not nil.
+func (ut *UsageTotalUpdate) SetNotNilStatus(value *uint8) *UsageTotalUpdate {
+	if value != nil {
+		return ut.SetStatus(*value)
+	}
+	return ut
+}
+
+// set field if value's pointer is not nil.
+func (ut *UsageTotalUpdateOne) SetNotNilStatus(value *uint8) *UsageTotalUpdateOne {
+	if value != nil {
+		return ut.SetStatus(*value)
+	}
+	return ut
+}
+
+// set field if value's pointer is not nil.
+func (ut *UsageTotalCreate) SetNotNilStatus(value *uint8) *UsageTotalCreate {
+	if value != nil {
+		return ut.SetStatus(*value)
+	}
+	return ut
+}
+
+// set field if value's pointer is not nil.
+func (ut *UsageTotalUpdate) SetNotNilType(value *int) *UsageTotalUpdate {
+	if value != nil {
+		return ut.SetType(*value)
+	}
+	return ut
+}
+
+// set field if value's pointer is not nil.
+func (ut *UsageTotalUpdateOne) SetNotNilType(value *int) *UsageTotalUpdateOne {
+	if value != nil {
+		return ut.SetType(*value)
+	}
+	return ut
+}
+
+// set field if value's pointer is not nil.
+func (ut *UsageTotalCreate) SetNotNilType(value *int) *UsageTotalCreate {
+	if value != nil {
+		return ut.SetType(*value)
+	}
+	return ut
+}
+
+// set field if value's pointer is not nil.
+func (ut *UsageTotalUpdate) SetNotNilBotID(value *string) *UsageTotalUpdate {
+	if value != nil {
+		return ut.SetBotID(*value)
+	}
+	return ut
+}
+
+// set field if value's pointer is not nil.
+func (ut *UsageTotalUpdateOne) SetNotNilBotID(value *string) *UsageTotalUpdateOne {
+	if value != nil {
+		return ut.SetBotID(*value)
+	}
+	return ut
+}
+
+// set field if value's pointer is not nil.
+func (ut *UsageTotalCreate) SetNotNilBotID(value *string) *UsageTotalCreate {
+	if value != nil {
+		return ut.SetBotID(*value)
+	}
+	return ut
+}
+
+// set field if value's pointer is not nil.
+func (ut *UsageTotalUpdate) SetNotNilTotalTokens(value *uint64) *UsageTotalUpdate {
+	if value != nil {
+		return ut.SetTotalTokens(*value)
+	}
+	return ut
+}
+
+// set field if value's pointer is not nil.
+func (ut *UsageTotalUpdateOne) SetNotNilTotalTokens(value *uint64) *UsageTotalUpdateOne {
+	if value != nil {
+		return ut.SetTotalTokens(*value)
+	}
+	return ut
+}
+
+// set field if value's pointer is not nil.
+func (ut *UsageTotalCreate) SetNotNilTotalTokens(value *uint64) *UsageTotalCreate {
+	if value != nil {
+		return ut.SetTotalTokens(*value)
+	}
+	return ut
+}
+
+// set field if value's pointer is not nil.
+func (ut *UsageTotalUpdate) SetNotNilStartIndex(value *uint64) *UsageTotalUpdate {
+	if value != nil {
+		return ut.SetStartIndex(*value)
+	}
+	return ut
+}
+
+// set field if value's pointer is not nil.
+func (ut *UsageTotalUpdateOne) SetNotNilStartIndex(value *uint64) *UsageTotalUpdateOne {
+	if value != nil {
+		return ut.SetStartIndex(*value)
+	}
+	return ut
+}
+
+// set field if value's pointer is not nil.
+func (ut *UsageTotalCreate) SetNotNilStartIndex(value *uint64) *UsageTotalCreate {
+	if value != nil {
+		return ut.SetStartIndex(*value)
+	}
+	return ut
+}
+
+// set field if value's pointer is not nil.
+func (ut *UsageTotalUpdate) SetNotNilEndIndex(value *uint64) *UsageTotalUpdate {
+	if value != nil {
+		return ut.SetEndIndex(*value)
+	}
+	return ut
+}
+
+// set field if value's pointer is not nil.
+func (ut *UsageTotalUpdateOne) SetNotNilEndIndex(value *uint64) *UsageTotalUpdateOne {
+	if value != nil {
+		return ut.SetEndIndex(*value)
+	}
+	return ut
+}
+
+// set field if value's pointer is not nil.
+func (ut *UsageTotalCreate) SetNotNilEndIndex(value *uint64) *UsageTotalCreate {
+	if value != nil {
+		return ut.SetEndIndex(*value)
+	}
+	return ut
+}
+
+// set field if value's pointer is not nil.
+func (ut *UsageTotalUpdate) SetNotNilOrganizationID(value *uint64) *UsageTotalUpdate {
+	if value != nil {
+		return ut.SetOrganizationID(*value)
+	}
+	return ut
+}
+
+// set field if value's pointer is not nil.
+func (ut *UsageTotalUpdateOne) SetNotNilOrganizationID(value *uint64) *UsageTotalUpdateOne {
+	if value != nil {
+		return ut.SetOrganizationID(*value)
+	}
+	return ut
+}
+
+// set field if value's pointer is not nil.
+func (ut *UsageTotalCreate) SetNotNilOrganizationID(value *uint64) *UsageTotalCreate {
+	if value != nil {
+		return ut.SetOrganizationID(*value)
+	}
+	return ut
+}
+
+// set field if value's pointer is not nil.
 func (we *WorkExperienceUpdate) SetNotNilUpdatedAt(value *time.Time) *WorkExperienceUpdate {
 	if value != nil {
 		return we.SetUpdatedAt(*value)

+ 6 - 0
ent/tx.go

@@ -56,6 +56,10 @@ type Tx struct {
 	Token *TokenClient
 	// Tutorial is the client for interacting with the Tutorial builders.
 	Tutorial *TutorialClient
+	// UsageDetail is the client for interacting with the UsageDetail builders.
+	UsageDetail *UsageDetailClient
+	// UsageTotal is the client for interacting with the UsageTotal builders.
+	UsageTotal *UsageTotalClient
 	// WorkExperience is the client for interacting with the WorkExperience builders.
 	WorkExperience *WorkExperienceClient
 	// Wx is the client for interacting with the Wx builders.
@@ -218,6 +222,8 @@ func (tx *Tx) init() {
 	tx.SopTask = NewSopTaskClient(tx.config)
 	tx.Token = NewTokenClient(tx.config)
 	tx.Tutorial = NewTutorialClient(tx.config)
+	tx.UsageDetail = NewUsageDetailClient(tx.config)
+	tx.UsageTotal = NewUsageTotalClient(tx.config)
 	tx.WorkExperience = NewWorkExperienceClient(tx.config)
 	tx.Wx = NewWxClient(tx.config)
 	tx.WxCard = NewWxCardClient(tx.config)

+ 249 - 0
ent/usagedetail.go

@@ -0,0 +1,249 @@
+// Code generated by ent, DO NOT EDIT.
+
+package ent
+
+import (
+	"fmt"
+	"strings"
+	"time"
+	"wechat-api/ent/usagedetail"
+
+	"entgo.io/ent"
+	"entgo.io/ent/dialect/sql"
+)
+
+// UsageDetail is the model entity for the UsageDetail schema.
+type UsageDetail struct {
+	config `json:"-"`
+	// ID of the ent.
+	ID uint64 `json:"id,omitempty"`
+	// Create Time | 创建日期
+	CreatedAt time.Time `json:"created_at,omitempty"`
+	// Update Time | 修改日期
+	UpdatedAt time.Time `json:"updated_at,omitempty"`
+	// Status 1: normal 2: ban | 状态 1 正常 2 禁用
+	Status uint8 `json:"status,omitempty"`
+	// 1 微信 2 名片
+	Type int `json:"type,omitempty"`
+	// 微信或名片id
+	BotID string `json:"bot_id,omitempty"`
+	// 微信id或open_id
+	ReceiverID string `json:"receiver_id,omitempty"`
+	// 1 cow-basic 2 cow-agent 3 cow-sop 4 mp-card 5 mp-employee
+	App int `json:"app,omitempty"`
+	// 名片会话id
+	SessionID uint64 `json:"session_id,omitempty"`
+	// 请求内容
+	Request string `json:"request,omitempty"`
+	// 响应内容
+	Response string `json:"response,omitempty"`
+	// 使用token总数
+	TotalTokens uint64 `json:"total_tokens,omitempty"`
+	// 请求token数
+	PromptTokens uint64 `json:"prompt_tokens,omitempty"`
+	// 响应token数
+	CompletionTokens uint64 `json:"completion_tokens,omitempty"`
+	// 机构 ID
+	OrganizationID uint64 `json:"organization_id,omitempty"`
+	selectValues   sql.SelectValues
+}
+
+// scanValues returns the types for scanning values from sql.Rows.
+func (*UsageDetail) scanValues(columns []string) ([]any, error) {
+	values := make([]any, len(columns))
+	for i := range columns {
+		switch columns[i] {
+		case usagedetail.FieldID, usagedetail.FieldStatus, usagedetail.FieldType, usagedetail.FieldApp, usagedetail.FieldSessionID, usagedetail.FieldTotalTokens, usagedetail.FieldPromptTokens, usagedetail.FieldCompletionTokens, usagedetail.FieldOrganizationID:
+			values[i] = new(sql.NullInt64)
+		case usagedetail.FieldBotID, usagedetail.FieldReceiverID, usagedetail.FieldRequest, usagedetail.FieldResponse:
+			values[i] = new(sql.NullString)
+		case usagedetail.FieldCreatedAt, usagedetail.FieldUpdatedAt:
+			values[i] = new(sql.NullTime)
+		default:
+			values[i] = new(sql.UnknownType)
+		}
+	}
+	return values, nil
+}
+
+// assignValues assigns the values that were returned from sql.Rows (after scanning)
+// to the UsageDetail fields.
+func (ud *UsageDetail) 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 usagedetail.FieldID:
+			value, ok := values[i].(*sql.NullInt64)
+			if !ok {
+				return fmt.Errorf("unexpected type %T for field id", value)
+			}
+			ud.ID = uint64(value.Int64)
+		case usagedetail.FieldCreatedAt:
+			if value, ok := values[i].(*sql.NullTime); !ok {
+				return fmt.Errorf("unexpected type %T for field created_at", values[i])
+			} else if value.Valid {
+				ud.CreatedAt = value.Time
+			}
+		case usagedetail.FieldUpdatedAt:
+			if value, ok := values[i].(*sql.NullTime); !ok {
+				return fmt.Errorf("unexpected type %T for field updated_at", values[i])
+			} else if value.Valid {
+				ud.UpdatedAt = value.Time
+			}
+		case usagedetail.FieldStatus:
+			if value, ok := values[i].(*sql.NullInt64); !ok {
+				return fmt.Errorf("unexpected type %T for field status", values[i])
+			} else if value.Valid {
+				ud.Status = uint8(value.Int64)
+			}
+		case usagedetail.FieldType:
+			if value, ok := values[i].(*sql.NullInt64); !ok {
+				return fmt.Errorf("unexpected type %T for field type", values[i])
+			} else if value.Valid {
+				ud.Type = int(value.Int64)
+			}
+		case usagedetail.FieldBotID:
+			if value, ok := values[i].(*sql.NullString); !ok {
+				return fmt.Errorf("unexpected type %T for field bot_id", values[i])
+			} else if value.Valid {
+				ud.BotID = value.String
+			}
+		case usagedetail.FieldReceiverID:
+			if value, ok := values[i].(*sql.NullString); !ok {
+				return fmt.Errorf("unexpected type %T for field receiver_id", values[i])
+			} else if value.Valid {
+				ud.ReceiverID = value.String
+			}
+		case usagedetail.FieldApp:
+			if value, ok := values[i].(*sql.NullInt64); !ok {
+				return fmt.Errorf("unexpected type %T for field app", values[i])
+			} else if value.Valid {
+				ud.App = int(value.Int64)
+			}
+		case usagedetail.FieldSessionID:
+			if value, ok := values[i].(*sql.NullInt64); !ok {
+				return fmt.Errorf("unexpected type %T for field session_id", values[i])
+			} else if value.Valid {
+				ud.SessionID = uint64(value.Int64)
+			}
+		case usagedetail.FieldRequest:
+			if value, ok := values[i].(*sql.NullString); !ok {
+				return fmt.Errorf("unexpected type %T for field request", values[i])
+			} else if value.Valid {
+				ud.Request = value.String
+			}
+		case usagedetail.FieldResponse:
+			if value, ok := values[i].(*sql.NullString); !ok {
+				return fmt.Errorf("unexpected type %T for field response", values[i])
+			} else if value.Valid {
+				ud.Response = value.String
+			}
+		case usagedetail.FieldTotalTokens:
+			if value, ok := values[i].(*sql.NullInt64); !ok {
+				return fmt.Errorf("unexpected type %T for field total_tokens", values[i])
+			} else if value.Valid {
+				ud.TotalTokens = uint64(value.Int64)
+			}
+		case usagedetail.FieldPromptTokens:
+			if value, ok := values[i].(*sql.NullInt64); !ok {
+				return fmt.Errorf("unexpected type %T for field prompt_tokens", values[i])
+			} else if value.Valid {
+				ud.PromptTokens = uint64(value.Int64)
+			}
+		case usagedetail.FieldCompletionTokens:
+			if value, ok := values[i].(*sql.NullInt64); !ok {
+				return fmt.Errorf("unexpected type %T for field completion_tokens", values[i])
+			} else if value.Valid {
+				ud.CompletionTokens = uint64(value.Int64)
+			}
+		case usagedetail.FieldOrganizationID:
+			if value, ok := values[i].(*sql.NullInt64); !ok {
+				return fmt.Errorf("unexpected type %T for field organization_id", values[i])
+			} else if value.Valid {
+				ud.OrganizationID = uint64(value.Int64)
+			}
+		default:
+			ud.selectValues.Set(columns[i], values[i])
+		}
+	}
+	return nil
+}
+
+// Value returns the ent.Value that was dynamically selected and assigned to the UsageDetail.
+// This includes values selected through modifiers, order, etc.
+func (ud *UsageDetail) Value(name string) (ent.Value, error) {
+	return ud.selectValues.Get(name)
+}
+
+// Update returns a builder for updating this UsageDetail.
+// Note that you need to call UsageDetail.Unwrap() before calling this method if this UsageDetail
+// was returned from a transaction, and the transaction was committed or rolled back.
+func (ud *UsageDetail) Update() *UsageDetailUpdateOne {
+	return NewUsageDetailClient(ud.config).UpdateOne(ud)
+}
+
+// Unwrap unwraps the UsageDetail 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 (ud *UsageDetail) Unwrap() *UsageDetail {
+	_tx, ok := ud.config.driver.(*txDriver)
+	if !ok {
+		panic("ent: UsageDetail is not a transactional entity")
+	}
+	ud.config.driver = _tx.drv
+	return ud
+}
+
+// String implements the fmt.Stringer.
+func (ud *UsageDetail) String() string {
+	var builder strings.Builder
+	builder.WriteString("UsageDetail(")
+	builder.WriteString(fmt.Sprintf("id=%v, ", ud.ID))
+	builder.WriteString("created_at=")
+	builder.WriteString(ud.CreatedAt.Format(time.ANSIC))
+	builder.WriteString(", ")
+	builder.WriteString("updated_at=")
+	builder.WriteString(ud.UpdatedAt.Format(time.ANSIC))
+	builder.WriteString(", ")
+	builder.WriteString("status=")
+	builder.WriteString(fmt.Sprintf("%v", ud.Status))
+	builder.WriteString(", ")
+	builder.WriteString("type=")
+	builder.WriteString(fmt.Sprintf("%v", ud.Type))
+	builder.WriteString(", ")
+	builder.WriteString("bot_id=")
+	builder.WriteString(ud.BotID)
+	builder.WriteString(", ")
+	builder.WriteString("receiver_id=")
+	builder.WriteString(ud.ReceiverID)
+	builder.WriteString(", ")
+	builder.WriteString("app=")
+	builder.WriteString(fmt.Sprintf("%v", ud.App))
+	builder.WriteString(", ")
+	builder.WriteString("session_id=")
+	builder.WriteString(fmt.Sprintf("%v", ud.SessionID))
+	builder.WriteString(", ")
+	builder.WriteString("request=")
+	builder.WriteString(ud.Request)
+	builder.WriteString(", ")
+	builder.WriteString("response=")
+	builder.WriteString(ud.Response)
+	builder.WriteString(", ")
+	builder.WriteString("total_tokens=")
+	builder.WriteString(fmt.Sprintf("%v", ud.TotalTokens))
+	builder.WriteString(", ")
+	builder.WriteString("prompt_tokens=")
+	builder.WriteString(fmt.Sprintf("%v", ud.PromptTokens))
+	builder.WriteString(", ")
+	builder.WriteString("completion_tokens=")
+	builder.WriteString(fmt.Sprintf("%v", ud.CompletionTokens))
+	builder.WriteString(", ")
+	builder.WriteString("organization_id=")
+	builder.WriteString(fmt.Sprintf("%v", ud.OrganizationID))
+	builder.WriteByte(')')
+	return builder.String()
+}
+
+// UsageDetails is a parsable slice of UsageDetail.
+type UsageDetails []*UsageDetail

+ 186 - 0
ent/usagedetail/usagedetail.go

@@ -0,0 +1,186 @@
+// Code generated by ent, DO NOT EDIT.
+
+package usagedetail
+
+import (
+	"time"
+
+	"entgo.io/ent/dialect/sql"
+)
+
+const (
+	// Label holds the string label denoting the usagedetail type in the database.
+	Label = "usage_detail"
+	// FieldID holds the string denoting the id field in the database.
+	FieldID = "id"
+	// FieldCreatedAt holds the string denoting the created_at field in the database.
+	FieldCreatedAt = "created_at"
+	// FieldUpdatedAt holds the string denoting the updated_at field in the database.
+	FieldUpdatedAt = "updated_at"
+	// FieldStatus holds the string denoting the status field in the database.
+	FieldStatus = "status"
+	// FieldType holds the string denoting the type field in the database.
+	FieldType = "type"
+	// FieldBotID holds the string denoting the bot_id field in the database.
+	FieldBotID = "bot_id"
+	// FieldReceiverID holds the string denoting the receiver_id field in the database.
+	FieldReceiverID = "receiver_id"
+	// FieldApp holds the string denoting the app field in the database.
+	FieldApp = "app"
+	// FieldSessionID holds the string denoting the session_id field in the database.
+	FieldSessionID = "session_id"
+	// FieldRequest holds the string denoting the request field in the database.
+	FieldRequest = "request"
+	// FieldResponse holds the string denoting the response field in the database.
+	FieldResponse = "response"
+	// FieldTotalTokens holds the string denoting the total_tokens field in the database.
+	FieldTotalTokens = "total_tokens"
+	// FieldPromptTokens holds the string denoting the prompt_tokens field in the database.
+	FieldPromptTokens = "prompt_tokens"
+	// FieldCompletionTokens holds the string denoting the completion_tokens field in the database.
+	FieldCompletionTokens = "completion_tokens"
+	// FieldOrganizationID holds the string denoting the organization_id field in the database.
+	FieldOrganizationID = "organization_id"
+	// Table holds the table name of the usagedetail in the database.
+	Table = "usage_detail"
+)
+
+// Columns holds all SQL columns for usagedetail fields.
+var Columns = []string{
+	FieldID,
+	FieldCreatedAt,
+	FieldUpdatedAt,
+	FieldStatus,
+	FieldType,
+	FieldBotID,
+	FieldReceiverID,
+	FieldApp,
+	FieldSessionID,
+	FieldRequest,
+	FieldResponse,
+	FieldTotalTokens,
+	FieldPromptTokens,
+	FieldCompletionTokens,
+	FieldOrganizationID,
+}
+
+// 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 (
+	// DefaultCreatedAt holds the default value on creation for the "created_at" field.
+	DefaultCreatedAt func() time.Time
+	// DefaultUpdatedAt holds the default value on creation for the "updated_at" field.
+	DefaultUpdatedAt func() time.Time
+	// UpdateDefaultUpdatedAt holds the default value on update for the "updated_at" field.
+	UpdateDefaultUpdatedAt func() time.Time
+	// DefaultStatus holds the default value on creation for the "status" field.
+	DefaultStatus uint8
+	// DefaultType holds the default value on creation for the "type" field.
+	DefaultType int
+	// DefaultBotID holds the default value on creation for the "bot_id" field.
+	DefaultBotID string
+	// DefaultReceiverID holds the default value on creation for the "receiver_id" field.
+	DefaultReceiverID string
+	// DefaultApp holds the default value on creation for the "app" field.
+	DefaultApp int
+	// DefaultSessionID holds the default value on creation for the "session_id" field.
+	DefaultSessionID uint64
+	// DefaultRequest holds the default value on creation for the "request" field.
+	DefaultRequest string
+	// DefaultResponse holds the default value on creation for the "response" field.
+	DefaultResponse string
+	// DefaultTotalTokens holds the default value on creation for the "total_tokens" field.
+	DefaultTotalTokens uint64
+	// DefaultPromptTokens holds the default value on creation for the "prompt_tokens" field.
+	DefaultPromptTokens uint64
+	// DefaultCompletionTokens holds the default value on creation for the "completion_tokens" field.
+	DefaultCompletionTokens uint64
+	// DefaultOrganizationID holds the default value on creation for the "organization_id" field.
+	DefaultOrganizationID uint64
+)
+
+// OrderOption defines the ordering options for the UsageDetail 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()
+}
+
+// ByCreatedAt orders the results by the created_at field.
+func ByCreatedAt(opts ...sql.OrderTermOption) OrderOption {
+	return sql.OrderByField(FieldCreatedAt, opts...).ToFunc()
+}
+
+// ByUpdatedAt orders the results by the updated_at field.
+func ByUpdatedAt(opts ...sql.OrderTermOption) OrderOption {
+	return sql.OrderByField(FieldUpdatedAt, opts...).ToFunc()
+}
+
+// ByStatus orders the results by the status field.
+func ByStatus(opts ...sql.OrderTermOption) OrderOption {
+	return sql.OrderByField(FieldStatus, opts...).ToFunc()
+}
+
+// ByType orders the results by the type field.
+func ByType(opts ...sql.OrderTermOption) OrderOption {
+	return sql.OrderByField(FieldType, opts...).ToFunc()
+}
+
+// ByBotID orders the results by the bot_id field.
+func ByBotID(opts ...sql.OrderTermOption) OrderOption {
+	return sql.OrderByField(FieldBotID, opts...).ToFunc()
+}
+
+// ByReceiverID orders the results by the receiver_id field.
+func ByReceiverID(opts ...sql.OrderTermOption) OrderOption {
+	return sql.OrderByField(FieldReceiverID, opts...).ToFunc()
+}
+
+// ByApp orders the results by the app field.
+func ByApp(opts ...sql.OrderTermOption) OrderOption {
+	return sql.OrderByField(FieldApp, opts...).ToFunc()
+}
+
+// BySessionID orders the results by the session_id field.
+func BySessionID(opts ...sql.OrderTermOption) OrderOption {
+	return sql.OrderByField(FieldSessionID, opts...).ToFunc()
+}
+
+// ByRequest orders the results by the request field.
+func ByRequest(opts ...sql.OrderTermOption) OrderOption {
+	return sql.OrderByField(FieldRequest, opts...).ToFunc()
+}
+
+// ByResponse orders the results by the response field.
+func ByResponse(opts ...sql.OrderTermOption) OrderOption {
+	return sql.OrderByField(FieldResponse, opts...).ToFunc()
+}
+
+// ByTotalTokens orders the results by the total_tokens field.
+func ByTotalTokens(opts ...sql.OrderTermOption) OrderOption {
+	return sql.OrderByField(FieldTotalTokens, opts...).ToFunc()
+}
+
+// ByPromptTokens orders the results by the prompt_tokens field.
+func ByPromptTokens(opts ...sql.OrderTermOption) OrderOption {
+	return sql.OrderByField(FieldPromptTokens, opts...).ToFunc()
+}
+
+// ByCompletionTokens orders the results by the completion_tokens field.
+func ByCompletionTokens(opts ...sql.OrderTermOption) OrderOption {
+	return sql.OrderByField(FieldCompletionTokens, opts...).ToFunc()
+}
+
+// ByOrganizationID orders the results by the organization_id field.
+func ByOrganizationID(opts ...sql.OrderTermOption) OrderOption {
+	return sql.OrderByField(FieldOrganizationID, opts...).ToFunc()
+}

+ 880 - 0
ent/usagedetail/where.go

@@ -0,0 +1,880 @@
+// Code generated by ent, DO NOT EDIT.
+
+package usagedetail
+
+import (
+	"time"
+	"wechat-api/ent/predicate"
+
+	"entgo.io/ent/dialect/sql"
+)
+
+// ID filters vertices based on their ID field.
+func ID(id uint64) predicate.UsageDetail {
+	return predicate.UsageDetail(sql.FieldEQ(FieldID, id))
+}
+
+// IDEQ applies the EQ predicate on the ID field.
+func IDEQ(id uint64) predicate.UsageDetail {
+	return predicate.UsageDetail(sql.FieldEQ(FieldID, id))
+}
+
+// IDNEQ applies the NEQ predicate on the ID field.
+func IDNEQ(id uint64) predicate.UsageDetail {
+	return predicate.UsageDetail(sql.FieldNEQ(FieldID, id))
+}
+
+// IDIn applies the In predicate on the ID field.
+func IDIn(ids ...uint64) predicate.UsageDetail {
+	return predicate.UsageDetail(sql.FieldIn(FieldID, ids...))
+}
+
+// IDNotIn applies the NotIn predicate on the ID field.
+func IDNotIn(ids ...uint64) predicate.UsageDetail {
+	return predicate.UsageDetail(sql.FieldNotIn(FieldID, ids...))
+}
+
+// IDGT applies the GT predicate on the ID field.
+func IDGT(id uint64) predicate.UsageDetail {
+	return predicate.UsageDetail(sql.FieldGT(FieldID, id))
+}
+
+// IDGTE applies the GTE predicate on the ID field.
+func IDGTE(id uint64) predicate.UsageDetail {
+	return predicate.UsageDetail(sql.FieldGTE(FieldID, id))
+}
+
+// IDLT applies the LT predicate on the ID field.
+func IDLT(id uint64) predicate.UsageDetail {
+	return predicate.UsageDetail(sql.FieldLT(FieldID, id))
+}
+
+// IDLTE applies the LTE predicate on the ID field.
+func IDLTE(id uint64) predicate.UsageDetail {
+	return predicate.UsageDetail(sql.FieldLTE(FieldID, id))
+}
+
+// CreatedAt applies equality check predicate on the "created_at" field. It's identical to CreatedAtEQ.
+func CreatedAt(v time.Time) predicate.UsageDetail {
+	return predicate.UsageDetail(sql.FieldEQ(FieldCreatedAt, v))
+}
+
+// UpdatedAt applies equality check predicate on the "updated_at" field. It's identical to UpdatedAtEQ.
+func UpdatedAt(v time.Time) predicate.UsageDetail {
+	return predicate.UsageDetail(sql.FieldEQ(FieldUpdatedAt, v))
+}
+
+// Status applies equality check predicate on the "status" field. It's identical to StatusEQ.
+func Status(v uint8) predicate.UsageDetail {
+	return predicate.UsageDetail(sql.FieldEQ(FieldStatus, v))
+}
+
+// Type applies equality check predicate on the "type" field. It's identical to TypeEQ.
+func Type(v int) predicate.UsageDetail {
+	return predicate.UsageDetail(sql.FieldEQ(FieldType, v))
+}
+
+// BotID applies equality check predicate on the "bot_id" field. It's identical to BotIDEQ.
+func BotID(v string) predicate.UsageDetail {
+	return predicate.UsageDetail(sql.FieldEQ(FieldBotID, v))
+}
+
+// ReceiverID applies equality check predicate on the "receiver_id" field. It's identical to ReceiverIDEQ.
+func ReceiverID(v string) predicate.UsageDetail {
+	return predicate.UsageDetail(sql.FieldEQ(FieldReceiverID, v))
+}
+
+// App applies equality check predicate on the "app" field. It's identical to AppEQ.
+func App(v int) predicate.UsageDetail {
+	return predicate.UsageDetail(sql.FieldEQ(FieldApp, v))
+}
+
+// SessionID applies equality check predicate on the "session_id" field. It's identical to SessionIDEQ.
+func SessionID(v uint64) predicate.UsageDetail {
+	return predicate.UsageDetail(sql.FieldEQ(FieldSessionID, v))
+}
+
+// Request applies equality check predicate on the "request" field. It's identical to RequestEQ.
+func Request(v string) predicate.UsageDetail {
+	return predicate.UsageDetail(sql.FieldEQ(FieldRequest, v))
+}
+
+// Response applies equality check predicate on the "response" field. It's identical to ResponseEQ.
+func Response(v string) predicate.UsageDetail {
+	return predicate.UsageDetail(sql.FieldEQ(FieldResponse, v))
+}
+
+// TotalTokens applies equality check predicate on the "total_tokens" field. It's identical to TotalTokensEQ.
+func TotalTokens(v uint64) predicate.UsageDetail {
+	return predicate.UsageDetail(sql.FieldEQ(FieldTotalTokens, v))
+}
+
+// PromptTokens applies equality check predicate on the "prompt_tokens" field. It's identical to PromptTokensEQ.
+func PromptTokens(v uint64) predicate.UsageDetail {
+	return predicate.UsageDetail(sql.FieldEQ(FieldPromptTokens, v))
+}
+
+// CompletionTokens applies equality check predicate on the "completion_tokens" field. It's identical to CompletionTokensEQ.
+func CompletionTokens(v uint64) predicate.UsageDetail {
+	return predicate.UsageDetail(sql.FieldEQ(FieldCompletionTokens, v))
+}
+
+// OrganizationID applies equality check predicate on the "organization_id" field. It's identical to OrganizationIDEQ.
+func OrganizationID(v uint64) predicate.UsageDetail {
+	return predicate.UsageDetail(sql.FieldEQ(FieldOrganizationID, v))
+}
+
+// CreatedAtEQ applies the EQ predicate on the "created_at" field.
+func CreatedAtEQ(v time.Time) predicate.UsageDetail {
+	return predicate.UsageDetail(sql.FieldEQ(FieldCreatedAt, v))
+}
+
+// CreatedAtNEQ applies the NEQ predicate on the "created_at" field.
+func CreatedAtNEQ(v time.Time) predicate.UsageDetail {
+	return predicate.UsageDetail(sql.FieldNEQ(FieldCreatedAt, v))
+}
+
+// CreatedAtIn applies the In predicate on the "created_at" field.
+func CreatedAtIn(vs ...time.Time) predicate.UsageDetail {
+	return predicate.UsageDetail(sql.FieldIn(FieldCreatedAt, vs...))
+}
+
+// CreatedAtNotIn applies the NotIn predicate on the "created_at" field.
+func CreatedAtNotIn(vs ...time.Time) predicate.UsageDetail {
+	return predicate.UsageDetail(sql.FieldNotIn(FieldCreatedAt, vs...))
+}
+
+// CreatedAtGT applies the GT predicate on the "created_at" field.
+func CreatedAtGT(v time.Time) predicate.UsageDetail {
+	return predicate.UsageDetail(sql.FieldGT(FieldCreatedAt, v))
+}
+
+// CreatedAtGTE applies the GTE predicate on the "created_at" field.
+func CreatedAtGTE(v time.Time) predicate.UsageDetail {
+	return predicate.UsageDetail(sql.FieldGTE(FieldCreatedAt, v))
+}
+
+// CreatedAtLT applies the LT predicate on the "created_at" field.
+func CreatedAtLT(v time.Time) predicate.UsageDetail {
+	return predicate.UsageDetail(sql.FieldLT(FieldCreatedAt, v))
+}
+
+// CreatedAtLTE applies the LTE predicate on the "created_at" field.
+func CreatedAtLTE(v time.Time) predicate.UsageDetail {
+	return predicate.UsageDetail(sql.FieldLTE(FieldCreatedAt, v))
+}
+
+// UpdatedAtEQ applies the EQ predicate on the "updated_at" field.
+func UpdatedAtEQ(v time.Time) predicate.UsageDetail {
+	return predicate.UsageDetail(sql.FieldEQ(FieldUpdatedAt, v))
+}
+
+// UpdatedAtNEQ applies the NEQ predicate on the "updated_at" field.
+func UpdatedAtNEQ(v time.Time) predicate.UsageDetail {
+	return predicate.UsageDetail(sql.FieldNEQ(FieldUpdatedAt, v))
+}
+
+// UpdatedAtIn applies the In predicate on the "updated_at" field.
+func UpdatedAtIn(vs ...time.Time) predicate.UsageDetail {
+	return predicate.UsageDetail(sql.FieldIn(FieldUpdatedAt, vs...))
+}
+
+// UpdatedAtNotIn applies the NotIn predicate on the "updated_at" field.
+func UpdatedAtNotIn(vs ...time.Time) predicate.UsageDetail {
+	return predicate.UsageDetail(sql.FieldNotIn(FieldUpdatedAt, vs...))
+}
+
+// UpdatedAtGT applies the GT predicate on the "updated_at" field.
+func UpdatedAtGT(v time.Time) predicate.UsageDetail {
+	return predicate.UsageDetail(sql.FieldGT(FieldUpdatedAt, v))
+}
+
+// UpdatedAtGTE applies the GTE predicate on the "updated_at" field.
+func UpdatedAtGTE(v time.Time) predicate.UsageDetail {
+	return predicate.UsageDetail(sql.FieldGTE(FieldUpdatedAt, v))
+}
+
+// UpdatedAtLT applies the LT predicate on the "updated_at" field.
+func UpdatedAtLT(v time.Time) predicate.UsageDetail {
+	return predicate.UsageDetail(sql.FieldLT(FieldUpdatedAt, v))
+}
+
+// UpdatedAtLTE applies the LTE predicate on the "updated_at" field.
+func UpdatedAtLTE(v time.Time) predicate.UsageDetail {
+	return predicate.UsageDetail(sql.FieldLTE(FieldUpdatedAt, v))
+}
+
+// StatusEQ applies the EQ predicate on the "status" field.
+func StatusEQ(v uint8) predicate.UsageDetail {
+	return predicate.UsageDetail(sql.FieldEQ(FieldStatus, v))
+}
+
+// StatusNEQ applies the NEQ predicate on the "status" field.
+func StatusNEQ(v uint8) predicate.UsageDetail {
+	return predicate.UsageDetail(sql.FieldNEQ(FieldStatus, v))
+}
+
+// StatusIn applies the In predicate on the "status" field.
+func StatusIn(vs ...uint8) predicate.UsageDetail {
+	return predicate.UsageDetail(sql.FieldIn(FieldStatus, vs...))
+}
+
+// StatusNotIn applies the NotIn predicate on the "status" field.
+func StatusNotIn(vs ...uint8) predicate.UsageDetail {
+	return predicate.UsageDetail(sql.FieldNotIn(FieldStatus, vs...))
+}
+
+// StatusGT applies the GT predicate on the "status" field.
+func StatusGT(v uint8) predicate.UsageDetail {
+	return predicate.UsageDetail(sql.FieldGT(FieldStatus, v))
+}
+
+// StatusGTE applies the GTE predicate on the "status" field.
+func StatusGTE(v uint8) predicate.UsageDetail {
+	return predicate.UsageDetail(sql.FieldGTE(FieldStatus, v))
+}
+
+// StatusLT applies the LT predicate on the "status" field.
+func StatusLT(v uint8) predicate.UsageDetail {
+	return predicate.UsageDetail(sql.FieldLT(FieldStatus, v))
+}
+
+// StatusLTE applies the LTE predicate on the "status" field.
+func StatusLTE(v uint8) predicate.UsageDetail {
+	return predicate.UsageDetail(sql.FieldLTE(FieldStatus, v))
+}
+
+// StatusIsNil applies the IsNil predicate on the "status" field.
+func StatusIsNil() predicate.UsageDetail {
+	return predicate.UsageDetail(sql.FieldIsNull(FieldStatus))
+}
+
+// StatusNotNil applies the NotNil predicate on the "status" field.
+func StatusNotNil() predicate.UsageDetail {
+	return predicate.UsageDetail(sql.FieldNotNull(FieldStatus))
+}
+
+// TypeEQ applies the EQ predicate on the "type" field.
+func TypeEQ(v int) predicate.UsageDetail {
+	return predicate.UsageDetail(sql.FieldEQ(FieldType, v))
+}
+
+// TypeNEQ applies the NEQ predicate on the "type" field.
+func TypeNEQ(v int) predicate.UsageDetail {
+	return predicate.UsageDetail(sql.FieldNEQ(FieldType, v))
+}
+
+// TypeIn applies the In predicate on the "type" field.
+func TypeIn(vs ...int) predicate.UsageDetail {
+	return predicate.UsageDetail(sql.FieldIn(FieldType, vs...))
+}
+
+// TypeNotIn applies the NotIn predicate on the "type" field.
+func TypeNotIn(vs ...int) predicate.UsageDetail {
+	return predicate.UsageDetail(sql.FieldNotIn(FieldType, vs...))
+}
+
+// TypeGT applies the GT predicate on the "type" field.
+func TypeGT(v int) predicate.UsageDetail {
+	return predicate.UsageDetail(sql.FieldGT(FieldType, v))
+}
+
+// TypeGTE applies the GTE predicate on the "type" field.
+func TypeGTE(v int) predicate.UsageDetail {
+	return predicate.UsageDetail(sql.FieldGTE(FieldType, v))
+}
+
+// TypeLT applies the LT predicate on the "type" field.
+func TypeLT(v int) predicate.UsageDetail {
+	return predicate.UsageDetail(sql.FieldLT(FieldType, v))
+}
+
+// TypeLTE applies the LTE predicate on the "type" field.
+func TypeLTE(v int) predicate.UsageDetail {
+	return predicate.UsageDetail(sql.FieldLTE(FieldType, v))
+}
+
+// TypeIsNil applies the IsNil predicate on the "type" field.
+func TypeIsNil() predicate.UsageDetail {
+	return predicate.UsageDetail(sql.FieldIsNull(FieldType))
+}
+
+// TypeNotNil applies the NotNil predicate on the "type" field.
+func TypeNotNil() predicate.UsageDetail {
+	return predicate.UsageDetail(sql.FieldNotNull(FieldType))
+}
+
+// BotIDEQ applies the EQ predicate on the "bot_id" field.
+func BotIDEQ(v string) predicate.UsageDetail {
+	return predicate.UsageDetail(sql.FieldEQ(FieldBotID, v))
+}
+
+// BotIDNEQ applies the NEQ predicate on the "bot_id" field.
+func BotIDNEQ(v string) predicate.UsageDetail {
+	return predicate.UsageDetail(sql.FieldNEQ(FieldBotID, v))
+}
+
+// BotIDIn applies the In predicate on the "bot_id" field.
+func BotIDIn(vs ...string) predicate.UsageDetail {
+	return predicate.UsageDetail(sql.FieldIn(FieldBotID, vs...))
+}
+
+// BotIDNotIn applies the NotIn predicate on the "bot_id" field.
+func BotIDNotIn(vs ...string) predicate.UsageDetail {
+	return predicate.UsageDetail(sql.FieldNotIn(FieldBotID, vs...))
+}
+
+// BotIDGT applies the GT predicate on the "bot_id" field.
+func BotIDGT(v string) predicate.UsageDetail {
+	return predicate.UsageDetail(sql.FieldGT(FieldBotID, v))
+}
+
+// BotIDGTE applies the GTE predicate on the "bot_id" field.
+func BotIDGTE(v string) predicate.UsageDetail {
+	return predicate.UsageDetail(sql.FieldGTE(FieldBotID, v))
+}
+
+// BotIDLT applies the LT predicate on the "bot_id" field.
+func BotIDLT(v string) predicate.UsageDetail {
+	return predicate.UsageDetail(sql.FieldLT(FieldBotID, v))
+}
+
+// BotIDLTE applies the LTE predicate on the "bot_id" field.
+func BotIDLTE(v string) predicate.UsageDetail {
+	return predicate.UsageDetail(sql.FieldLTE(FieldBotID, v))
+}
+
+// BotIDContains applies the Contains predicate on the "bot_id" field.
+func BotIDContains(v string) predicate.UsageDetail {
+	return predicate.UsageDetail(sql.FieldContains(FieldBotID, v))
+}
+
+// BotIDHasPrefix applies the HasPrefix predicate on the "bot_id" field.
+func BotIDHasPrefix(v string) predicate.UsageDetail {
+	return predicate.UsageDetail(sql.FieldHasPrefix(FieldBotID, v))
+}
+
+// BotIDHasSuffix applies the HasSuffix predicate on the "bot_id" field.
+func BotIDHasSuffix(v string) predicate.UsageDetail {
+	return predicate.UsageDetail(sql.FieldHasSuffix(FieldBotID, v))
+}
+
+// BotIDEqualFold applies the EqualFold predicate on the "bot_id" field.
+func BotIDEqualFold(v string) predicate.UsageDetail {
+	return predicate.UsageDetail(sql.FieldEqualFold(FieldBotID, v))
+}
+
+// BotIDContainsFold applies the ContainsFold predicate on the "bot_id" field.
+func BotIDContainsFold(v string) predicate.UsageDetail {
+	return predicate.UsageDetail(sql.FieldContainsFold(FieldBotID, v))
+}
+
+// ReceiverIDEQ applies the EQ predicate on the "receiver_id" field.
+func ReceiverIDEQ(v string) predicate.UsageDetail {
+	return predicate.UsageDetail(sql.FieldEQ(FieldReceiverID, v))
+}
+
+// ReceiverIDNEQ applies the NEQ predicate on the "receiver_id" field.
+func ReceiverIDNEQ(v string) predicate.UsageDetail {
+	return predicate.UsageDetail(sql.FieldNEQ(FieldReceiverID, v))
+}
+
+// ReceiverIDIn applies the In predicate on the "receiver_id" field.
+func ReceiverIDIn(vs ...string) predicate.UsageDetail {
+	return predicate.UsageDetail(sql.FieldIn(FieldReceiverID, vs...))
+}
+
+// ReceiverIDNotIn applies the NotIn predicate on the "receiver_id" field.
+func ReceiverIDNotIn(vs ...string) predicate.UsageDetail {
+	return predicate.UsageDetail(sql.FieldNotIn(FieldReceiverID, vs...))
+}
+
+// ReceiverIDGT applies the GT predicate on the "receiver_id" field.
+func ReceiverIDGT(v string) predicate.UsageDetail {
+	return predicate.UsageDetail(sql.FieldGT(FieldReceiverID, v))
+}
+
+// ReceiverIDGTE applies the GTE predicate on the "receiver_id" field.
+func ReceiverIDGTE(v string) predicate.UsageDetail {
+	return predicate.UsageDetail(sql.FieldGTE(FieldReceiverID, v))
+}
+
+// ReceiverIDLT applies the LT predicate on the "receiver_id" field.
+func ReceiverIDLT(v string) predicate.UsageDetail {
+	return predicate.UsageDetail(sql.FieldLT(FieldReceiverID, v))
+}
+
+// ReceiverIDLTE applies the LTE predicate on the "receiver_id" field.
+func ReceiverIDLTE(v string) predicate.UsageDetail {
+	return predicate.UsageDetail(sql.FieldLTE(FieldReceiverID, v))
+}
+
+// ReceiverIDContains applies the Contains predicate on the "receiver_id" field.
+func ReceiverIDContains(v string) predicate.UsageDetail {
+	return predicate.UsageDetail(sql.FieldContains(FieldReceiverID, v))
+}
+
+// ReceiverIDHasPrefix applies the HasPrefix predicate on the "receiver_id" field.
+func ReceiverIDHasPrefix(v string) predicate.UsageDetail {
+	return predicate.UsageDetail(sql.FieldHasPrefix(FieldReceiverID, v))
+}
+
+// ReceiverIDHasSuffix applies the HasSuffix predicate on the "receiver_id" field.
+func ReceiverIDHasSuffix(v string) predicate.UsageDetail {
+	return predicate.UsageDetail(sql.FieldHasSuffix(FieldReceiverID, v))
+}
+
+// ReceiverIDEqualFold applies the EqualFold predicate on the "receiver_id" field.
+func ReceiverIDEqualFold(v string) predicate.UsageDetail {
+	return predicate.UsageDetail(sql.FieldEqualFold(FieldReceiverID, v))
+}
+
+// ReceiverIDContainsFold applies the ContainsFold predicate on the "receiver_id" field.
+func ReceiverIDContainsFold(v string) predicate.UsageDetail {
+	return predicate.UsageDetail(sql.FieldContainsFold(FieldReceiverID, v))
+}
+
+// AppEQ applies the EQ predicate on the "app" field.
+func AppEQ(v int) predicate.UsageDetail {
+	return predicate.UsageDetail(sql.FieldEQ(FieldApp, v))
+}
+
+// AppNEQ applies the NEQ predicate on the "app" field.
+func AppNEQ(v int) predicate.UsageDetail {
+	return predicate.UsageDetail(sql.FieldNEQ(FieldApp, v))
+}
+
+// AppIn applies the In predicate on the "app" field.
+func AppIn(vs ...int) predicate.UsageDetail {
+	return predicate.UsageDetail(sql.FieldIn(FieldApp, vs...))
+}
+
+// AppNotIn applies the NotIn predicate on the "app" field.
+func AppNotIn(vs ...int) predicate.UsageDetail {
+	return predicate.UsageDetail(sql.FieldNotIn(FieldApp, vs...))
+}
+
+// AppGT applies the GT predicate on the "app" field.
+func AppGT(v int) predicate.UsageDetail {
+	return predicate.UsageDetail(sql.FieldGT(FieldApp, v))
+}
+
+// AppGTE applies the GTE predicate on the "app" field.
+func AppGTE(v int) predicate.UsageDetail {
+	return predicate.UsageDetail(sql.FieldGTE(FieldApp, v))
+}
+
+// AppLT applies the LT predicate on the "app" field.
+func AppLT(v int) predicate.UsageDetail {
+	return predicate.UsageDetail(sql.FieldLT(FieldApp, v))
+}
+
+// AppLTE applies the LTE predicate on the "app" field.
+func AppLTE(v int) predicate.UsageDetail {
+	return predicate.UsageDetail(sql.FieldLTE(FieldApp, v))
+}
+
+// AppIsNil applies the IsNil predicate on the "app" field.
+func AppIsNil() predicate.UsageDetail {
+	return predicate.UsageDetail(sql.FieldIsNull(FieldApp))
+}
+
+// AppNotNil applies the NotNil predicate on the "app" field.
+func AppNotNil() predicate.UsageDetail {
+	return predicate.UsageDetail(sql.FieldNotNull(FieldApp))
+}
+
+// SessionIDEQ applies the EQ predicate on the "session_id" field.
+func SessionIDEQ(v uint64) predicate.UsageDetail {
+	return predicate.UsageDetail(sql.FieldEQ(FieldSessionID, v))
+}
+
+// SessionIDNEQ applies the NEQ predicate on the "session_id" field.
+func SessionIDNEQ(v uint64) predicate.UsageDetail {
+	return predicate.UsageDetail(sql.FieldNEQ(FieldSessionID, v))
+}
+
+// SessionIDIn applies the In predicate on the "session_id" field.
+func SessionIDIn(vs ...uint64) predicate.UsageDetail {
+	return predicate.UsageDetail(sql.FieldIn(FieldSessionID, vs...))
+}
+
+// SessionIDNotIn applies the NotIn predicate on the "session_id" field.
+func SessionIDNotIn(vs ...uint64) predicate.UsageDetail {
+	return predicate.UsageDetail(sql.FieldNotIn(FieldSessionID, vs...))
+}
+
+// SessionIDGT applies the GT predicate on the "session_id" field.
+func SessionIDGT(v uint64) predicate.UsageDetail {
+	return predicate.UsageDetail(sql.FieldGT(FieldSessionID, v))
+}
+
+// SessionIDGTE applies the GTE predicate on the "session_id" field.
+func SessionIDGTE(v uint64) predicate.UsageDetail {
+	return predicate.UsageDetail(sql.FieldGTE(FieldSessionID, v))
+}
+
+// SessionIDLT applies the LT predicate on the "session_id" field.
+func SessionIDLT(v uint64) predicate.UsageDetail {
+	return predicate.UsageDetail(sql.FieldLT(FieldSessionID, v))
+}
+
+// SessionIDLTE applies the LTE predicate on the "session_id" field.
+func SessionIDLTE(v uint64) predicate.UsageDetail {
+	return predicate.UsageDetail(sql.FieldLTE(FieldSessionID, v))
+}
+
+// SessionIDIsNil applies the IsNil predicate on the "session_id" field.
+func SessionIDIsNil() predicate.UsageDetail {
+	return predicate.UsageDetail(sql.FieldIsNull(FieldSessionID))
+}
+
+// SessionIDNotNil applies the NotNil predicate on the "session_id" field.
+func SessionIDNotNil() predicate.UsageDetail {
+	return predicate.UsageDetail(sql.FieldNotNull(FieldSessionID))
+}
+
+// RequestEQ applies the EQ predicate on the "request" field.
+func RequestEQ(v string) predicate.UsageDetail {
+	return predicate.UsageDetail(sql.FieldEQ(FieldRequest, v))
+}
+
+// RequestNEQ applies the NEQ predicate on the "request" field.
+func RequestNEQ(v string) predicate.UsageDetail {
+	return predicate.UsageDetail(sql.FieldNEQ(FieldRequest, v))
+}
+
+// RequestIn applies the In predicate on the "request" field.
+func RequestIn(vs ...string) predicate.UsageDetail {
+	return predicate.UsageDetail(sql.FieldIn(FieldRequest, vs...))
+}
+
+// RequestNotIn applies the NotIn predicate on the "request" field.
+func RequestNotIn(vs ...string) predicate.UsageDetail {
+	return predicate.UsageDetail(sql.FieldNotIn(FieldRequest, vs...))
+}
+
+// RequestGT applies the GT predicate on the "request" field.
+func RequestGT(v string) predicate.UsageDetail {
+	return predicate.UsageDetail(sql.FieldGT(FieldRequest, v))
+}
+
+// RequestGTE applies the GTE predicate on the "request" field.
+func RequestGTE(v string) predicate.UsageDetail {
+	return predicate.UsageDetail(sql.FieldGTE(FieldRequest, v))
+}
+
+// RequestLT applies the LT predicate on the "request" field.
+func RequestLT(v string) predicate.UsageDetail {
+	return predicate.UsageDetail(sql.FieldLT(FieldRequest, v))
+}
+
+// RequestLTE applies the LTE predicate on the "request" field.
+func RequestLTE(v string) predicate.UsageDetail {
+	return predicate.UsageDetail(sql.FieldLTE(FieldRequest, v))
+}
+
+// RequestContains applies the Contains predicate on the "request" field.
+func RequestContains(v string) predicate.UsageDetail {
+	return predicate.UsageDetail(sql.FieldContains(FieldRequest, v))
+}
+
+// RequestHasPrefix applies the HasPrefix predicate on the "request" field.
+func RequestHasPrefix(v string) predicate.UsageDetail {
+	return predicate.UsageDetail(sql.FieldHasPrefix(FieldRequest, v))
+}
+
+// RequestHasSuffix applies the HasSuffix predicate on the "request" field.
+func RequestHasSuffix(v string) predicate.UsageDetail {
+	return predicate.UsageDetail(sql.FieldHasSuffix(FieldRequest, v))
+}
+
+// RequestEqualFold applies the EqualFold predicate on the "request" field.
+func RequestEqualFold(v string) predicate.UsageDetail {
+	return predicate.UsageDetail(sql.FieldEqualFold(FieldRequest, v))
+}
+
+// RequestContainsFold applies the ContainsFold predicate on the "request" field.
+func RequestContainsFold(v string) predicate.UsageDetail {
+	return predicate.UsageDetail(sql.FieldContainsFold(FieldRequest, v))
+}
+
+// ResponseEQ applies the EQ predicate on the "response" field.
+func ResponseEQ(v string) predicate.UsageDetail {
+	return predicate.UsageDetail(sql.FieldEQ(FieldResponse, v))
+}
+
+// ResponseNEQ applies the NEQ predicate on the "response" field.
+func ResponseNEQ(v string) predicate.UsageDetail {
+	return predicate.UsageDetail(sql.FieldNEQ(FieldResponse, v))
+}
+
+// ResponseIn applies the In predicate on the "response" field.
+func ResponseIn(vs ...string) predicate.UsageDetail {
+	return predicate.UsageDetail(sql.FieldIn(FieldResponse, vs...))
+}
+
+// ResponseNotIn applies the NotIn predicate on the "response" field.
+func ResponseNotIn(vs ...string) predicate.UsageDetail {
+	return predicate.UsageDetail(sql.FieldNotIn(FieldResponse, vs...))
+}
+
+// ResponseGT applies the GT predicate on the "response" field.
+func ResponseGT(v string) predicate.UsageDetail {
+	return predicate.UsageDetail(sql.FieldGT(FieldResponse, v))
+}
+
+// ResponseGTE applies the GTE predicate on the "response" field.
+func ResponseGTE(v string) predicate.UsageDetail {
+	return predicate.UsageDetail(sql.FieldGTE(FieldResponse, v))
+}
+
+// ResponseLT applies the LT predicate on the "response" field.
+func ResponseLT(v string) predicate.UsageDetail {
+	return predicate.UsageDetail(sql.FieldLT(FieldResponse, v))
+}
+
+// ResponseLTE applies the LTE predicate on the "response" field.
+func ResponseLTE(v string) predicate.UsageDetail {
+	return predicate.UsageDetail(sql.FieldLTE(FieldResponse, v))
+}
+
+// ResponseContains applies the Contains predicate on the "response" field.
+func ResponseContains(v string) predicate.UsageDetail {
+	return predicate.UsageDetail(sql.FieldContains(FieldResponse, v))
+}
+
+// ResponseHasPrefix applies the HasPrefix predicate on the "response" field.
+func ResponseHasPrefix(v string) predicate.UsageDetail {
+	return predicate.UsageDetail(sql.FieldHasPrefix(FieldResponse, v))
+}
+
+// ResponseHasSuffix applies the HasSuffix predicate on the "response" field.
+func ResponseHasSuffix(v string) predicate.UsageDetail {
+	return predicate.UsageDetail(sql.FieldHasSuffix(FieldResponse, v))
+}
+
+// ResponseEqualFold applies the EqualFold predicate on the "response" field.
+func ResponseEqualFold(v string) predicate.UsageDetail {
+	return predicate.UsageDetail(sql.FieldEqualFold(FieldResponse, v))
+}
+
+// ResponseContainsFold applies the ContainsFold predicate on the "response" field.
+func ResponseContainsFold(v string) predicate.UsageDetail {
+	return predicate.UsageDetail(sql.FieldContainsFold(FieldResponse, v))
+}
+
+// TotalTokensEQ applies the EQ predicate on the "total_tokens" field.
+func TotalTokensEQ(v uint64) predicate.UsageDetail {
+	return predicate.UsageDetail(sql.FieldEQ(FieldTotalTokens, v))
+}
+
+// TotalTokensNEQ applies the NEQ predicate on the "total_tokens" field.
+func TotalTokensNEQ(v uint64) predicate.UsageDetail {
+	return predicate.UsageDetail(sql.FieldNEQ(FieldTotalTokens, v))
+}
+
+// TotalTokensIn applies the In predicate on the "total_tokens" field.
+func TotalTokensIn(vs ...uint64) predicate.UsageDetail {
+	return predicate.UsageDetail(sql.FieldIn(FieldTotalTokens, vs...))
+}
+
+// TotalTokensNotIn applies the NotIn predicate on the "total_tokens" field.
+func TotalTokensNotIn(vs ...uint64) predicate.UsageDetail {
+	return predicate.UsageDetail(sql.FieldNotIn(FieldTotalTokens, vs...))
+}
+
+// TotalTokensGT applies the GT predicate on the "total_tokens" field.
+func TotalTokensGT(v uint64) predicate.UsageDetail {
+	return predicate.UsageDetail(sql.FieldGT(FieldTotalTokens, v))
+}
+
+// TotalTokensGTE applies the GTE predicate on the "total_tokens" field.
+func TotalTokensGTE(v uint64) predicate.UsageDetail {
+	return predicate.UsageDetail(sql.FieldGTE(FieldTotalTokens, v))
+}
+
+// TotalTokensLT applies the LT predicate on the "total_tokens" field.
+func TotalTokensLT(v uint64) predicate.UsageDetail {
+	return predicate.UsageDetail(sql.FieldLT(FieldTotalTokens, v))
+}
+
+// TotalTokensLTE applies the LTE predicate on the "total_tokens" field.
+func TotalTokensLTE(v uint64) predicate.UsageDetail {
+	return predicate.UsageDetail(sql.FieldLTE(FieldTotalTokens, v))
+}
+
+// TotalTokensIsNil applies the IsNil predicate on the "total_tokens" field.
+func TotalTokensIsNil() predicate.UsageDetail {
+	return predicate.UsageDetail(sql.FieldIsNull(FieldTotalTokens))
+}
+
+// TotalTokensNotNil applies the NotNil predicate on the "total_tokens" field.
+func TotalTokensNotNil() predicate.UsageDetail {
+	return predicate.UsageDetail(sql.FieldNotNull(FieldTotalTokens))
+}
+
+// PromptTokensEQ applies the EQ predicate on the "prompt_tokens" field.
+func PromptTokensEQ(v uint64) predicate.UsageDetail {
+	return predicate.UsageDetail(sql.FieldEQ(FieldPromptTokens, v))
+}
+
+// PromptTokensNEQ applies the NEQ predicate on the "prompt_tokens" field.
+func PromptTokensNEQ(v uint64) predicate.UsageDetail {
+	return predicate.UsageDetail(sql.FieldNEQ(FieldPromptTokens, v))
+}
+
+// PromptTokensIn applies the In predicate on the "prompt_tokens" field.
+func PromptTokensIn(vs ...uint64) predicate.UsageDetail {
+	return predicate.UsageDetail(sql.FieldIn(FieldPromptTokens, vs...))
+}
+
+// PromptTokensNotIn applies the NotIn predicate on the "prompt_tokens" field.
+func PromptTokensNotIn(vs ...uint64) predicate.UsageDetail {
+	return predicate.UsageDetail(sql.FieldNotIn(FieldPromptTokens, vs...))
+}
+
+// PromptTokensGT applies the GT predicate on the "prompt_tokens" field.
+func PromptTokensGT(v uint64) predicate.UsageDetail {
+	return predicate.UsageDetail(sql.FieldGT(FieldPromptTokens, v))
+}
+
+// PromptTokensGTE applies the GTE predicate on the "prompt_tokens" field.
+func PromptTokensGTE(v uint64) predicate.UsageDetail {
+	return predicate.UsageDetail(sql.FieldGTE(FieldPromptTokens, v))
+}
+
+// PromptTokensLT applies the LT predicate on the "prompt_tokens" field.
+func PromptTokensLT(v uint64) predicate.UsageDetail {
+	return predicate.UsageDetail(sql.FieldLT(FieldPromptTokens, v))
+}
+
+// PromptTokensLTE applies the LTE predicate on the "prompt_tokens" field.
+func PromptTokensLTE(v uint64) predicate.UsageDetail {
+	return predicate.UsageDetail(sql.FieldLTE(FieldPromptTokens, v))
+}
+
+// PromptTokensIsNil applies the IsNil predicate on the "prompt_tokens" field.
+func PromptTokensIsNil() predicate.UsageDetail {
+	return predicate.UsageDetail(sql.FieldIsNull(FieldPromptTokens))
+}
+
+// PromptTokensNotNil applies the NotNil predicate on the "prompt_tokens" field.
+func PromptTokensNotNil() predicate.UsageDetail {
+	return predicate.UsageDetail(sql.FieldNotNull(FieldPromptTokens))
+}
+
+// CompletionTokensEQ applies the EQ predicate on the "completion_tokens" field.
+func CompletionTokensEQ(v uint64) predicate.UsageDetail {
+	return predicate.UsageDetail(sql.FieldEQ(FieldCompletionTokens, v))
+}
+
+// CompletionTokensNEQ applies the NEQ predicate on the "completion_tokens" field.
+func CompletionTokensNEQ(v uint64) predicate.UsageDetail {
+	return predicate.UsageDetail(sql.FieldNEQ(FieldCompletionTokens, v))
+}
+
+// CompletionTokensIn applies the In predicate on the "completion_tokens" field.
+func CompletionTokensIn(vs ...uint64) predicate.UsageDetail {
+	return predicate.UsageDetail(sql.FieldIn(FieldCompletionTokens, vs...))
+}
+
+// CompletionTokensNotIn applies the NotIn predicate on the "completion_tokens" field.
+func CompletionTokensNotIn(vs ...uint64) predicate.UsageDetail {
+	return predicate.UsageDetail(sql.FieldNotIn(FieldCompletionTokens, vs...))
+}
+
+// CompletionTokensGT applies the GT predicate on the "completion_tokens" field.
+func CompletionTokensGT(v uint64) predicate.UsageDetail {
+	return predicate.UsageDetail(sql.FieldGT(FieldCompletionTokens, v))
+}
+
+// CompletionTokensGTE applies the GTE predicate on the "completion_tokens" field.
+func CompletionTokensGTE(v uint64) predicate.UsageDetail {
+	return predicate.UsageDetail(sql.FieldGTE(FieldCompletionTokens, v))
+}
+
+// CompletionTokensLT applies the LT predicate on the "completion_tokens" field.
+func CompletionTokensLT(v uint64) predicate.UsageDetail {
+	return predicate.UsageDetail(sql.FieldLT(FieldCompletionTokens, v))
+}
+
+// CompletionTokensLTE applies the LTE predicate on the "completion_tokens" field.
+func CompletionTokensLTE(v uint64) predicate.UsageDetail {
+	return predicate.UsageDetail(sql.FieldLTE(FieldCompletionTokens, v))
+}
+
+// CompletionTokensIsNil applies the IsNil predicate on the "completion_tokens" field.
+func CompletionTokensIsNil() predicate.UsageDetail {
+	return predicate.UsageDetail(sql.FieldIsNull(FieldCompletionTokens))
+}
+
+// CompletionTokensNotNil applies the NotNil predicate on the "completion_tokens" field.
+func CompletionTokensNotNil() predicate.UsageDetail {
+	return predicate.UsageDetail(sql.FieldNotNull(FieldCompletionTokens))
+}
+
+// OrganizationIDEQ applies the EQ predicate on the "organization_id" field.
+func OrganizationIDEQ(v uint64) predicate.UsageDetail {
+	return predicate.UsageDetail(sql.FieldEQ(FieldOrganizationID, v))
+}
+
+// OrganizationIDNEQ applies the NEQ predicate on the "organization_id" field.
+func OrganizationIDNEQ(v uint64) predicate.UsageDetail {
+	return predicate.UsageDetail(sql.FieldNEQ(FieldOrganizationID, v))
+}
+
+// OrganizationIDIn applies the In predicate on the "organization_id" field.
+func OrganizationIDIn(vs ...uint64) predicate.UsageDetail {
+	return predicate.UsageDetail(sql.FieldIn(FieldOrganizationID, vs...))
+}
+
+// OrganizationIDNotIn applies the NotIn predicate on the "organization_id" field.
+func OrganizationIDNotIn(vs ...uint64) predicate.UsageDetail {
+	return predicate.UsageDetail(sql.FieldNotIn(FieldOrganizationID, vs...))
+}
+
+// OrganizationIDGT applies the GT predicate on the "organization_id" field.
+func OrganizationIDGT(v uint64) predicate.UsageDetail {
+	return predicate.UsageDetail(sql.FieldGT(FieldOrganizationID, v))
+}
+
+// OrganizationIDGTE applies the GTE predicate on the "organization_id" field.
+func OrganizationIDGTE(v uint64) predicate.UsageDetail {
+	return predicate.UsageDetail(sql.FieldGTE(FieldOrganizationID, v))
+}
+
+// OrganizationIDLT applies the LT predicate on the "organization_id" field.
+func OrganizationIDLT(v uint64) predicate.UsageDetail {
+	return predicate.UsageDetail(sql.FieldLT(FieldOrganizationID, v))
+}
+
+// OrganizationIDLTE applies the LTE predicate on the "organization_id" field.
+func OrganizationIDLTE(v uint64) predicate.UsageDetail {
+	return predicate.UsageDetail(sql.FieldLTE(FieldOrganizationID, v))
+}
+
+// OrganizationIDIsNil applies the IsNil predicate on the "organization_id" field.
+func OrganizationIDIsNil() predicate.UsageDetail {
+	return predicate.UsageDetail(sql.FieldIsNull(FieldOrganizationID))
+}
+
+// OrganizationIDNotNil applies the NotNil predicate on the "organization_id" field.
+func OrganizationIDNotNil() predicate.UsageDetail {
+	return predicate.UsageDetail(sql.FieldNotNull(FieldOrganizationID))
+}
+
+// And groups predicates with the AND operator between them.
+func And(predicates ...predicate.UsageDetail) predicate.UsageDetail {
+	return predicate.UsageDetail(sql.AndPredicates(predicates...))
+}
+
+// Or groups predicates with the OR operator between them.
+func Or(predicates ...predicate.UsageDetail) predicate.UsageDetail {
+	return predicate.UsageDetail(sql.OrPredicates(predicates...))
+}
+
+// Not applies the not operator on the given predicate.
+func Not(p predicate.UsageDetail) predicate.UsageDetail {
+	return predicate.UsageDetail(sql.NotPredicates(p))
+}

+ 1610 - 0
ent/usagedetail_create.go

@@ -0,0 +1,1610 @@
+// Code generated by ent, DO NOT EDIT.
+
+package ent
+
+import (
+	"context"
+	"errors"
+	"fmt"
+	"time"
+	"wechat-api/ent/usagedetail"
+
+	"entgo.io/ent/dialect/sql"
+	"entgo.io/ent/dialect/sql/sqlgraph"
+	"entgo.io/ent/schema/field"
+)
+
+// UsageDetailCreate is the builder for creating a UsageDetail entity.
+type UsageDetailCreate struct {
+	config
+	mutation *UsageDetailMutation
+	hooks    []Hook
+	conflict []sql.ConflictOption
+}
+
+// SetCreatedAt sets the "created_at" field.
+func (udc *UsageDetailCreate) SetCreatedAt(t time.Time) *UsageDetailCreate {
+	udc.mutation.SetCreatedAt(t)
+	return udc
+}
+
+// SetNillableCreatedAt sets the "created_at" field if the given value is not nil.
+func (udc *UsageDetailCreate) SetNillableCreatedAt(t *time.Time) *UsageDetailCreate {
+	if t != nil {
+		udc.SetCreatedAt(*t)
+	}
+	return udc
+}
+
+// SetUpdatedAt sets the "updated_at" field.
+func (udc *UsageDetailCreate) SetUpdatedAt(t time.Time) *UsageDetailCreate {
+	udc.mutation.SetUpdatedAt(t)
+	return udc
+}
+
+// SetNillableUpdatedAt sets the "updated_at" field if the given value is not nil.
+func (udc *UsageDetailCreate) SetNillableUpdatedAt(t *time.Time) *UsageDetailCreate {
+	if t != nil {
+		udc.SetUpdatedAt(*t)
+	}
+	return udc
+}
+
+// SetStatus sets the "status" field.
+func (udc *UsageDetailCreate) SetStatus(u uint8) *UsageDetailCreate {
+	udc.mutation.SetStatus(u)
+	return udc
+}
+
+// SetNillableStatus sets the "status" field if the given value is not nil.
+func (udc *UsageDetailCreate) SetNillableStatus(u *uint8) *UsageDetailCreate {
+	if u != nil {
+		udc.SetStatus(*u)
+	}
+	return udc
+}
+
+// SetType sets the "type" field.
+func (udc *UsageDetailCreate) SetType(i int) *UsageDetailCreate {
+	udc.mutation.SetType(i)
+	return udc
+}
+
+// SetNillableType sets the "type" field if the given value is not nil.
+func (udc *UsageDetailCreate) SetNillableType(i *int) *UsageDetailCreate {
+	if i != nil {
+		udc.SetType(*i)
+	}
+	return udc
+}
+
+// SetBotID sets the "bot_id" field.
+func (udc *UsageDetailCreate) SetBotID(s string) *UsageDetailCreate {
+	udc.mutation.SetBotID(s)
+	return udc
+}
+
+// SetNillableBotID sets the "bot_id" field if the given value is not nil.
+func (udc *UsageDetailCreate) SetNillableBotID(s *string) *UsageDetailCreate {
+	if s != nil {
+		udc.SetBotID(*s)
+	}
+	return udc
+}
+
+// SetReceiverID sets the "receiver_id" field.
+func (udc *UsageDetailCreate) SetReceiverID(s string) *UsageDetailCreate {
+	udc.mutation.SetReceiverID(s)
+	return udc
+}
+
+// SetNillableReceiverID sets the "receiver_id" field if the given value is not nil.
+func (udc *UsageDetailCreate) SetNillableReceiverID(s *string) *UsageDetailCreate {
+	if s != nil {
+		udc.SetReceiverID(*s)
+	}
+	return udc
+}
+
+// SetApp sets the "app" field.
+func (udc *UsageDetailCreate) SetApp(i int) *UsageDetailCreate {
+	udc.mutation.SetApp(i)
+	return udc
+}
+
+// SetNillableApp sets the "app" field if the given value is not nil.
+func (udc *UsageDetailCreate) SetNillableApp(i *int) *UsageDetailCreate {
+	if i != nil {
+		udc.SetApp(*i)
+	}
+	return udc
+}
+
+// SetSessionID sets the "session_id" field.
+func (udc *UsageDetailCreate) SetSessionID(u uint64) *UsageDetailCreate {
+	udc.mutation.SetSessionID(u)
+	return udc
+}
+
+// SetNillableSessionID sets the "session_id" field if the given value is not nil.
+func (udc *UsageDetailCreate) SetNillableSessionID(u *uint64) *UsageDetailCreate {
+	if u != nil {
+		udc.SetSessionID(*u)
+	}
+	return udc
+}
+
+// SetRequest sets the "request" field.
+func (udc *UsageDetailCreate) SetRequest(s string) *UsageDetailCreate {
+	udc.mutation.SetRequest(s)
+	return udc
+}
+
+// SetNillableRequest sets the "request" field if the given value is not nil.
+func (udc *UsageDetailCreate) SetNillableRequest(s *string) *UsageDetailCreate {
+	if s != nil {
+		udc.SetRequest(*s)
+	}
+	return udc
+}
+
+// SetResponse sets the "response" field.
+func (udc *UsageDetailCreate) SetResponse(s string) *UsageDetailCreate {
+	udc.mutation.SetResponse(s)
+	return udc
+}
+
+// SetNillableResponse sets the "response" field if the given value is not nil.
+func (udc *UsageDetailCreate) SetNillableResponse(s *string) *UsageDetailCreate {
+	if s != nil {
+		udc.SetResponse(*s)
+	}
+	return udc
+}
+
+// SetTotalTokens sets the "total_tokens" field.
+func (udc *UsageDetailCreate) SetTotalTokens(u uint64) *UsageDetailCreate {
+	udc.mutation.SetTotalTokens(u)
+	return udc
+}
+
+// SetNillableTotalTokens sets the "total_tokens" field if the given value is not nil.
+func (udc *UsageDetailCreate) SetNillableTotalTokens(u *uint64) *UsageDetailCreate {
+	if u != nil {
+		udc.SetTotalTokens(*u)
+	}
+	return udc
+}
+
+// SetPromptTokens sets the "prompt_tokens" field.
+func (udc *UsageDetailCreate) SetPromptTokens(u uint64) *UsageDetailCreate {
+	udc.mutation.SetPromptTokens(u)
+	return udc
+}
+
+// SetNillablePromptTokens sets the "prompt_tokens" field if the given value is not nil.
+func (udc *UsageDetailCreate) SetNillablePromptTokens(u *uint64) *UsageDetailCreate {
+	if u != nil {
+		udc.SetPromptTokens(*u)
+	}
+	return udc
+}
+
+// SetCompletionTokens sets the "completion_tokens" field.
+func (udc *UsageDetailCreate) SetCompletionTokens(u uint64) *UsageDetailCreate {
+	udc.mutation.SetCompletionTokens(u)
+	return udc
+}
+
+// SetNillableCompletionTokens sets the "completion_tokens" field if the given value is not nil.
+func (udc *UsageDetailCreate) SetNillableCompletionTokens(u *uint64) *UsageDetailCreate {
+	if u != nil {
+		udc.SetCompletionTokens(*u)
+	}
+	return udc
+}
+
+// SetOrganizationID sets the "organization_id" field.
+func (udc *UsageDetailCreate) SetOrganizationID(u uint64) *UsageDetailCreate {
+	udc.mutation.SetOrganizationID(u)
+	return udc
+}
+
+// SetNillableOrganizationID sets the "organization_id" field if the given value is not nil.
+func (udc *UsageDetailCreate) SetNillableOrganizationID(u *uint64) *UsageDetailCreate {
+	if u != nil {
+		udc.SetOrganizationID(*u)
+	}
+	return udc
+}
+
+// SetID sets the "id" field.
+func (udc *UsageDetailCreate) SetID(u uint64) *UsageDetailCreate {
+	udc.mutation.SetID(u)
+	return udc
+}
+
+// Mutation returns the UsageDetailMutation object of the builder.
+func (udc *UsageDetailCreate) Mutation() *UsageDetailMutation {
+	return udc.mutation
+}
+
+// Save creates the UsageDetail in the database.
+func (udc *UsageDetailCreate) Save(ctx context.Context) (*UsageDetail, error) {
+	udc.defaults()
+	return withHooks(ctx, udc.sqlSave, udc.mutation, udc.hooks)
+}
+
+// SaveX calls Save and panics if Save returns an error.
+func (udc *UsageDetailCreate) SaveX(ctx context.Context) *UsageDetail {
+	v, err := udc.Save(ctx)
+	if err != nil {
+		panic(err)
+	}
+	return v
+}
+
+// Exec executes the query.
+func (udc *UsageDetailCreate) Exec(ctx context.Context) error {
+	_, err := udc.Save(ctx)
+	return err
+}
+
+// ExecX is like Exec, but panics if an error occurs.
+func (udc *UsageDetailCreate) ExecX(ctx context.Context) {
+	if err := udc.Exec(ctx); err != nil {
+		panic(err)
+	}
+}
+
+// defaults sets the default values of the builder before save.
+func (udc *UsageDetailCreate) defaults() {
+	if _, ok := udc.mutation.CreatedAt(); !ok {
+		v := usagedetail.DefaultCreatedAt()
+		udc.mutation.SetCreatedAt(v)
+	}
+	if _, ok := udc.mutation.UpdatedAt(); !ok {
+		v := usagedetail.DefaultUpdatedAt()
+		udc.mutation.SetUpdatedAt(v)
+	}
+	if _, ok := udc.mutation.Status(); !ok {
+		v := usagedetail.DefaultStatus
+		udc.mutation.SetStatus(v)
+	}
+	if _, ok := udc.mutation.GetType(); !ok {
+		v := usagedetail.DefaultType
+		udc.mutation.SetType(v)
+	}
+	if _, ok := udc.mutation.BotID(); !ok {
+		v := usagedetail.DefaultBotID
+		udc.mutation.SetBotID(v)
+	}
+	if _, ok := udc.mutation.ReceiverID(); !ok {
+		v := usagedetail.DefaultReceiverID
+		udc.mutation.SetReceiverID(v)
+	}
+	if _, ok := udc.mutation.App(); !ok {
+		v := usagedetail.DefaultApp
+		udc.mutation.SetApp(v)
+	}
+	if _, ok := udc.mutation.SessionID(); !ok {
+		v := usagedetail.DefaultSessionID
+		udc.mutation.SetSessionID(v)
+	}
+	if _, ok := udc.mutation.Request(); !ok {
+		v := usagedetail.DefaultRequest
+		udc.mutation.SetRequest(v)
+	}
+	if _, ok := udc.mutation.Response(); !ok {
+		v := usagedetail.DefaultResponse
+		udc.mutation.SetResponse(v)
+	}
+	if _, ok := udc.mutation.TotalTokens(); !ok {
+		v := usagedetail.DefaultTotalTokens
+		udc.mutation.SetTotalTokens(v)
+	}
+	if _, ok := udc.mutation.PromptTokens(); !ok {
+		v := usagedetail.DefaultPromptTokens
+		udc.mutation.SetPromptTokens(v)
+	}
+	if _, ok := udc.mutation.CompletionTokens(); !ok {
+		v := usagedetail.DefaultCompletionTokens
+		udc.mutation.SetCompletionTokens(v)
+	}
+	if _, ok := udc.mutation.OrganizationID(); !ok {
+		v := usagedetail.DefaultOrganizationID
+		udc.mutation.SetOrganizationID(v)
+	}
+}
+
+// check runs all checks and user-defined validators on the builder.
+func (udc *UsageDetailCreate) check() error {
+	if _, ok := udc.mutation.CreatedAt(); !ok {
+		return &ValidationError{Name: "created_at", err: errors.New(`ent: missing required field "UsageDetail.created_at"`)}
+	}
+	if _, ok := udc.mutation.UpdatedAt(); !ok {
+		return &ValidationError{Name: "updated_at", err: errors.New(`ent: missing required field "UsageDetail.updated_at"`)}
+	}
+	if _, ok := udc.mutation.BotID(); !ok {
+		return &ValidationError{Name: "bot_id", err: errors.New(`ent: missing required field "UsageDetail.bot_id"`)}
+	}
+	if _, ok := udc.mutation.ReceiverID(); !ok {
+		return &ValidationError{Name: "receiver_id", err: errors.New(`ent: missing required field "UsageDetail.receiver_id"`)}
+	}
+	if _, ok := udc.mutation.Request(); !ok {
+		return &ValidationError{Name: "request", err: errors.New(`ent: missing required field "UsageDetail.request"`)}
+	}
+	if _, ok := udc.mutation.Response(); !ok {
+		return &ValidationError{Name: "response", err: errors.New(`ent: missing required field "UsageDetail.response"`)}
+	}
+	return nil
+}
+
+func (udc *UsageDetailCreate) sqlSave(ctx context.Context) (*UsageDetail, error) {
+	if err := udc.check(); err != nil {
+		return nil, err
+	}
+	_node, _spec := udc.createSpec()
+	if err := sqlgraph.CreateNode(ctx, udc.driver, _spec); err != nil {
+		if sqlgraph.IsConstraintError(err) {
+			err = &ConstraintError{msg: err.Error(), wrap: err}
+		}
+		return nil, err
+	}
+	if _spec.ID.Value != _node.ID {
+		id := _spec.ID.Value.(int64)
+		_node.ID = uint64(id)
+	}
+	udc.mutation.id = &_node.ID
+	udc.mutation.done = true
+	return _node, nil
+}
+
+func (udc *UsageDetailCreate) createSpec() (*UsageDetail, *sqlgraph.CreateSpec) {
+	var (
+		_node = &UsageDetail{config: udc.config}
+		_spec = sqlgraph.NewCreateSpec(usagedetail.Table, sqlgraph.NewFieldSpec(usagedetail.FieldID, field.TypeUint64))
+	)
+	_spec.OnConflict = udc.conflict
+	if id, ok := udc.mutation.ID(); ok {
+		_node.ID = id
+		_spec.ID.Value = id
+	}
+	if value, ok := udc.mutation.CreatedAt(); ok {
+		_spec.SetField(usagedetail.FieldCreatedAt, field.TypeTime, value)
+		_node.CreatedAt = value
+	}
+	if value, ok := udc.mutation.UpdatedAt(); ok {
+		_spec.SetField(usagedetail.FieldUpdatedAt, field.TypeTime, value)
+		_node.UpdatedAt = value
+	}
+	if value, ok := udc.mutation.Status(); ok {
+		_spec.SetField(usagedetail.FieldStatus, field.TypeUint8, value)
+		_node.Status = value
+	}
+	if value, ok := udc.mutation.GetType(); ok {
+		_spec.SetField(usagedetail.FieldType, field.TypeInt, value)
+		_node.Type = value
+	}
+	if value, ok := udc.mutation.BotID(); ok {
+		_spec.SetField(usagedetail.FieldBotID, field.TypeString, value)
+		_node.BotID = value
+	}
+	if value, ok := udc.mutation.ReceiverID(); ok {
+		_spec.SetField(usagedetail.FieldReceiverID, field.TypeString, value)
+		_node.ReceiverID = value
+	}
+	if value, ok := udc.mutation.App(); ok {
+		_spec.SetField(usagedetail.FieldApp, field.TypeInt, value)
+		_node.App = value
+	}
+	if value, ok := udc.mutation.SessionID(); ok {
+		_spec.SetField(usagedetail.FieldSessionID, field.TypeUint64, value)
+		_node.SessionID = value
+	}
+	if value, ok := udc.mutation.Request(); ok {
+		_spec.SetField(usagedetail.FieldRequest, field.TypeString, value)
+		_node.Request = value
+	}
+	if value, ok := udc.mutation.Response(); ok {
+		_spec.SetField(usagedetail.FieldResponse, field.TypeString, value)
+		_node.Response = value
+	}
+	if value, ok := udc.mutation.TotalTokens(); ok {
+		_spec.SetField(usagedetail.FieldTotalTokens, field.TypeUint64, value)
+		_node.TotalTokens = value
+	}
+	if value, ok := udc.mutation.PromptTokens(); ok {
+		_spec.SetField(usagedetail.FieldPromptTokens, field.TypeUint64, value)
+		_node.PromptTokens = value
+	}
+	if value, ok := udc.mutation.CompletionTokens(); ok {
+		_spec.SetField(usagedetail.FieldCompletionTokens, field.TypeUint64, value)
+		_node.CompletionTokens = value
+	}
+	if value, ok := udc.mutation.OrganizationID(); ok {
+		_spec.SetField(usagedetail.FieldOrganizationID, field.TypeUint64, value)
+		_node.OrganizationID = value
+	}
+	return _node, _spec
+}
+
+// OnConflict allows configuring the `ON CONFLICT` / `ON DUPLICATE KEY` clause
+// of the `INSERT` statement. For example:
+//
+//	client.UsageDetail.Create().
+//		SetCreatedAt(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.UsageDetailUpsert) {
+//			SetCreatedAt(v+v).
+//		}).
+//		Exec(ctx)
+func (udc *UsageDetailCreate) OnConflict(opts ...sql.ConflictOption) *UsageDetailUpsertOne {
+	udc.conflict = opts
+	return &UsageDetailUpsertOne{
+		create: udc,
+	}
+}
+
+// OnConflictColumns calls `OnConflict` and configures the columns
+// as conflict target. Using this option is equivalent to using:
+//
+//	client.UsageDetail.Create().
+//		OnConflict(sql.ConflictColumns(columns...)).
+//		Exec(ctx)
+func (udc *UsageDetailCreate) OnConflictColumns(columns ...string) *UsageDetailUpsertOne {
+	udc.conflict = append(udc.conflict, sql.ConflictColumns(columns...))
+	return &UsageDetailUpsertOne{
+		create: udc,
+	}
+}
+
+type (
+	// UsageDetailUpsertOne is the builder for "upsert"-ing
+	//  one UsageDetail node.
+	UsageDetailUpsertOne struct {
+		create *UsageDetailCreate
+	}
+
+	// UsageDetailUpsert is the "OnConflict" setter.
+	UsageDetailUpsert struct {
+		*sql.UpdateSet
+	}
+)
+
+// SetUpdatedAt sets the "updated_at" field.
+func (u *UsageDetailUpsert) SetUpdatedAt(v time.Time) *UsageDetailUpsert {
+	u.Set(usagedetail.FieldUpdatedAt, v)
+	return u
+}
+
+// UpdateUpdatedAt sets the "updated_at" field to the value that was provided on create.
+func (u *UsageDetailUpsert) UpdateUpdatedAt() *UsageDetailUpsert {
+	u.SetExcluded(usagedetail.FieldUpdatedAt)
+	return u
+}
+
+// SetStatus sets the "status" field.
+func (u *UsageDetailUpsert) SetStatus(v uint8) *UsageDetailUpsert {
+	u.Set(usagedetail.FieldStatus, v)
+	return u
+}
+
+// UpdateStatus sets the "status" field to the value that was provided on create.
+func (u *UsageDetailUpsert) UpdateStatus() *UsageDetailUpsert {
+	u.SetExcluded(usagedetail.FieldStatus)
+	return u
+}
+
+// AddStatus adds v to the "status" field.
+func (u *UsageDetailUpsert) AddStatus(v uint8) *UsageDetailUpsert {
+	u.Add(usagedetail.FieldStatus, v)
+	return u
+}
+
+// ClearStatus clears the value of the "status" field.
+func (u *UsageDetailUpsert) ClearStatus() *UsageDetailUpsert {
+	u.SetNull(usagedetail.FieldStatus)
+	return u
+}
+
+// SetType sets the "type" field.
+func (u *UsageDetailUpsert) SetType(v int) *UsageDetailUpsert {
+	u.Set(usagedetail.FieldType, v)
+	return u
+}
+
+// UpdateType sets the "type" field to the value that was provided on create.
+func (u *UsageDetailUpsert) UpdateType() *UsageDetailUpsert {
+	u.SetExcluded(usagedetail.FieldType)
+	return u
+}
+
+// AddType adds v to the "type" field.
+func (u *UsageDetailUpsert) AddType(v int) *UsageDetailUpsert {
+	u.Add(usagedetail.FieldType, v)
+	return u
+}
+
+// ClearType clears the value of the "type" field.
+func (u *UsageDetailUpsert) ClearType() *UsageDetailUpsert {
+	u.SetNull(usagedetail.FieldType)
+	return u
+}
+
+// SetBotID sets the "bot_id" field.
+func (u *UsageDetailUpsert) SetBotID(v string) *UsageDetailUpsert {
+	u.Set(usagedetail.FieldBotID, v)
+	return u
+}
+
+// UpdateBotID sets the "bot_id" field to the value that was provided on create.
+func (u *UsageDetailUpsert) UpdateBotID() *UsageDetailUpsert {
+	u.SetExcluded(usagedetail.FieldBotID)
+	return u
+}
+
+// SetReceiverID sets the "receiver_id" field.
+func (u *UsageDetailUpsert) SetReceiverID(v string) *UsageDetailUpsert {
+	u.Set(usagedetail.FieldReceiverID, v)
+	return u
+}
+
+// UpdateReceiverID sets the "receiver_id" field to the value that was provided on create.
+func (u *UsageDetailUpsert) UpdateReceiverID() *UsageDetailUpsert {
+	u.SetExcluded(usagedetail.FieldReceiverID)
+	return u
+}
+
+// SetApp sets the "app" field.
+func (u *UsageDetailUpsert) SetApp(v int) *UsageDetailUpsert {
+	u.Set(usagedetail.FieldApp, v)
+	return u
+}
+
+// UpdateApp sets the "app" field to the value that was provided on create.
+func (u *UsageDetailUpsert) UpdateApp() *UsageDetailUpsert {
+	u.SetExcluded(usagedetail.FieldApp)
+	return u
+}
+
+// AddApp adds v to the "app" field.
+func (u *UsageDetailUpsert) AddApp(v int) *UsageDetailUpsert {
+	u.Add(usagedetail.FieldApp, v)
+	return u
+}
+
+// ClearApp clears the value of the "app" field.
+func (u *UsageDetailUpsert) ClearApp() *UsageDetailUpsert {
+	u.SetNull(usagedetail.FieldApp)
+	return u
+}
+
+// SetSessionID sets the "session_id" field.
+func (u *UsageDetailUpsert) SetSessionID(v uint64) *UsageDetailUpsert {
+	u.Set(usagedetail.FieldSessionID, v)
+	return u
+}
+
+// UpdateSessionID sets the "session_id" field to the value that was provided on create.
+func (u *UsageDetailUpsert) UpdateSessionID() *UsageDetailUpsert {
+	u.SetExcluded(usagedetail.FieldSessionID)
+	return u
+}
+
+// AddSessionID adds v to the "session_id" field.
+func (u *UsageDetailUpsert) AddSessionID(v uint64) *UsageDetailUpsert {
+	u.Add(usagedetail.FieldSessionID, v)
+	return u
+}
+
+// ClearSessionID clears the value of the "session_id" field.
+func (u *UsageDetailUpsert) ClearSessionID() *UsageDetailUpsert {
+	u.SetNull(usagedetail.FieldSessionID)
+	return u
+}
+
+// SetRequest sets the "request" field.
+func (u *UsageDetailUpsert) SetRequest(v string) *UsageDetailUpsert {
+	u.Set(usagedetail.FieldRequest, v)
+	return u
+}
+
+// UpdateRequest sets the "request" field to the value that was provided on create.
+func (u *UsageDetailUpsert) UpdateRequest() *UsageDetailUpsert {
+	u.SetExcluded(usagedetail.FieldRequest)
+	return u
+}
+
+// SetResponse sets the "response" field.
+func (u *UsageDetailUpsert) SetResponse(v string) *UsageDetailUpsert {
+	u.Set(usagedetail.FieldResponse, v)
+	return u
+}
+
+// UpdateResponse sets the "response" field to the value that was provided on create.
+func (u *UsageDetailUpsert) UpdateResponse() *UsageDetailUpsert {
+	u.SetExcluded(usagedetail.FieldResponse)
+	return u
+}
+
+// SetTotalTokens sets the "total_tokens" field.
+func (u *UsageDetailUpsert) SetTotalTokens(v uint64) *UsageDetailUpsert {
+	u.Set(usagedetail.FieldTotalTokens, v)
+	return u
+}
+
+// UpdateTotalTokens sets the "total_tokens" field to the value that was provided on create.
+func (u *UsageDetailUpsert) UpdateTotalTokens() *UsageDetailUpsert {
+	u.SetExcluded(usagedetail.FieldTotalTokens)
+	return u
+}
+
+// AddTotalTokens adds v to the "total_tokens" field.
+func (u *UsageDetailUpsert) AddTotalTokens(v uint64) *UsageDetailUpsert {
+	u.Add(usagedetail.FieldTotalTokens, v)
+	return u
+}
+
+// ClearTotalTokens clears the value of the "total_tokens" field.
+func (u *UsageDetailUpsert) ClearTotalTokens() *UsageDetailUpsert {
+	u.SetNull(usagedetail.FieldTotalTokens)
+	return u
+}
+
+// SetPromptTokens sets the "prompt_tokens" field.
+func (u *UsageDetailUpsert) SetPromptTokens(v uint64) *UsageDetailUpsert {
+	u.Set(usagedetail.FieldPromptTokens, v)
+	return u
+}
+
+// UpdatePromptTokens sets the "prompt_tokens" field to the value that was provided on create.
+func (u *UsageDetailUpsert) UpdatePromptTokens() *UsageDetailUpsert {
+	u.SetExcluded(usagedetail.FieldPromptTokens)
+	return u
+}
+
+// AddPromptTokens adds v to the "prompt_tokens" field.
+func (u *UsageDetailUpsert) AddPromptTokens(v uint64) *UsageDetailUpsert {
+	u.Add(usagedetail.FieldPromptTokens, v)
+	return u
+}
+
+// ClearPromptTokens clears the value of the "prompt_tokens" field.
+func (u *UsageDetailUpsert) ClearPromptTokens() *UsageDetailUpsert {
+	u.SetNull(usagedetail.FieldPromptTokens)
+	return u
+}
+
+// SetCompletionTokens sets the "completion_tokens" field.
+func (u *UsageDetailUpsert) SetCompletionTokens(v uint64) *UsageDetailUpsert {
+	u.Set(usagedetail.FieldCompletionTokens, v)
+	return u
+}
+
+// UpdateCompletionTokens sets the "completion_tokens" field to the value that was provided on create.
+func (u *UsageDetailUpsert) UpdateCompletionTokens() *UsageDetailUpsert {
+	u.SetExcluded(usagedetail.FieldCompletionTokens)
+	return u
+}
+
+// AddCompletionTokens adds v to the "completion_tokens" field.
+func (u *UsageDetailUpsert) AddCompletionTokens(v uint64) *UsageDetailUpsert {
+	u.Add(usagedetail.FieldCompletionTokens, v)
+	return u
+}
+
+// ClearCompletionTokens clears the value of the "completion_tokens" field.
+func (u *UsageDetailUpsert) ClearCompletionTokens() *UsageDetailUpsert {
+	u.SetNull(usagedetail.FieldCompletionTokens)
+	return u
+}
+
+// SetOrganizationID sets the "organization_id" field.
+func (u *UsageDetailUpsert) SetOrganizationID(v uint64) *UsageDetailUpsert {
+	u.Set(usagedetail.FieldOrganizationID, v)
+	return u
+}
+
+// UpdateOrganizationID sets the "organization_id" field to the value that was provided on create.
+func (u *UsageDetailUpsert) UpdateOrganizationID() *UsageDetailUpsert {
+	u.SetExcluded(usagedetail.FieldOrganizationID)
+	return u
+}
+
+// AddOrganizationID adds v to the "organization_id" field.
+func (u *UsageDetailUpsert) AddOrganizationID(v uint64) *UsageDetailUpsert {
+	u.Add(usagedetail.FieldOrganizationID, v)
+	return u
+}
+
+// ClearOrganizationID clears the value of the "organization_id" field.
+func (u *UsageDetailUpsert) ClearOrganizationID() *UsageDetailUpsert {
+	u.SetNull(usagedetail.FieldOrganizationID)
+	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.UsageDetail.Create().
+//		OnConflict(
+//			sql.ResolveWithNewValues(),
+//			sql.ResolveWith(func(u *sql.UpdateSet) {
+//				u.SetIgnore(usagedetail.FieldID)
+//			}),
+//		).
+//		Exec(ctx)
+func (u *UsageDetailUpsertOne) UpdateNewValues() *UsageDetailUpsertOne {
+	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(usagedetail.FieldID)
+		}
+		if _, exists := u.create.mutation.CreatedAt(); exists {
+			s.SetIgnore(usagedetail.FieldCreatedAt)
+		}
+	}))
+	return u
+}
+
+// Ignore sets each column to itself in case of conflict.
+// Using this option is equivalent to using:
+//
+//	client.UsageDetail.Create().
+//	    OnConflict(sql.ResolveWithIgnore()).
+//	    Exec(ctx)
+func (u *UsageDetailUpsertOne) Ignore() *UsageDetailUpsertOne {
+	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 *UsageDetailUpsertOne) DoNothing() *UsageDetailUpsertOne {
+	u.create.conflict = append(u.create.conflict, sql.DoNothing())
+	return u
+}
+
+// Update allows overriding fields `UPDATE` values. See the UsageDetailCreate.OnConflict
+// documentation for more info.
+func (u *UsageDetailUpsertOne) Update(set func(*UsageDetailUpsert)) *UsageDetailUpsertOne {
+	u.create.conflict = append(u.create.conflict, sql.ResolveWith(func(update *sql.UpdateSet) {
+		set(&UsageDetailUpsert{UpdateSet: update})
+	}))
+	return u
+}
+
+// SetUpdatedAt sets the "updated_at" field.
+func (u *UsageDetailUpsertOne) SetUpdatedAt(v time.Time) *UsageDetailUpsertOne {
+	return u.Update(func(s *UsageDetailUpsert) {
+		s.SetUpdatedAt(v)
+	})
+}
+
+// UpdateUpdatedAt sets the "updated_at" field to the value that was provided on create.
+func (u *UsageDetailUpsertOne) UpdateUpdatedAt() *UsageDetailUpsertOne {
+	return u.Update(func(s *UsageDetailUpsert) {
+		s.UpdateUpdatedAt()
+	})
+}
+
+// SetStatus sets the "status" field.
+func (u *UsageDetailUpsertOne) SetStatus(v uint8) *UsageDetailUpsertOne {
+	return u.Update(func(s *UsageDetailUpsert) {
+		s.SetStatus(v)
+	})
+}
+
+// AddStatus adds v to the "status" field.
+func (u *UsageDetailUpsertOne) AddStatus(v uint8) *UsageDetailUpsertOne {
+	return u.Update(func(s *UsageDetailUpsert) {
+		s.AddStatus(v)
+	})
+}
+
+// UpdateStatus sets the "status" field to the value that was provided on create.
+func (u *UsageDetailUpsertOne) UpdateStatus() *UsageDetailUpsertOne {
+	return u.Update(func(s *UsageDetailUpsert) {
+		s.UpdateStatus()
+	})
+}
+
+// ClearStatus clears the value of the "status" field.
+func (u *UsageDetailUpsertOne) ClearStatus() *UsageDetailUpsertOne {
+	return u.Update(func(s *UsageDetailUpsert) {
+		s.ClearStatus()
+	})
+}
+
+// SetType sets the "type" field.
+func (u *UsageDetailUpsertOne) SetType(v int) *UsageDetailUpsertOne {
+	return u.Update(func(s *UsageDetailUpsert) {
+		s.SetType(v)
+	})
+}
+
+// AddType adds v to the "type" field.
+func (u *UsageDetailUpsertOne) AddType(v int) *UsageDetailUpsertOne {
+	return u.Update(func(s *UsageDetailUpsert) {
+		s.AddType(v)
+	})
+}
+
+// UpdateType sets the "type" field to the value that was provided on create.
+func (u *UsageDetailUpsertOne) UpdateType() *UsageDetailUpsertOne {
+	return u.Update(func(s *UsageDetailUpsert) {
+		s.UpdateType()
+	})
+}
+
+// ClearType clears the value of the "type" field.
+func (u *UsageDetailUpsertOne) ClearType() *UsageDetailUpsertOne {
+	return u.Update(func(s *UsageDetailUpsert) {
+		s.ClearType()
+	})
+}
+
+// SetBotID sets the "bot_id" field.
+func (u *UsageDetailUpsertOne) SetBotID(v string) *UsageDetailUpsertOne {
+	return u.Update(func(s *UsageDetailUpsert) {
+		s.SetBotID(v)
+	})
+}
+
+// UpdateBotID sets the "bot_id" field to the value that was provided on create.
+func (u *UsageDetailUpsertOne) UpdateBotID() *UsageDetailUpsertOne {
+	return u.Update(func(s *UsageDetailUpsert) {
+		s.UpdateBotID()
+	})
+}
+
+// SetReceiverID sets the "receiver_id" field.
+func (u *UsageDetailUpsertOne) SetReceiverID(v string) *UsageDetailUpsertOne {
+	return u.Update(func(s *UsageDetailUpsert) {
+		s.SetReceiverID(v)
+	})
+}
+
+// UpdateReceiverID sets the "receiver_id" field to the value that was provided on create.
+func (u *UsageDetailUpsertOne) UpdateReceiverID() *UsageDetailUpsertOne {
+	return u.Update(func(s *UsageDetailUpsert) {
+		s.UpdateReceiverID()
+	})
+}
+
+// SetApp sets the "app" field.
+func (u *UsageDetailUpsertOne) SetApp(v int) *UsageDetailUpsertOne {
+	return u.Update(func(s *UsageDetailUpsert) {
+		s.SetApp(v)
+	})
+}
+
+// AddApp adds v to the "app" field.
+func (u *UsageDetailUpsertOne) AddApp(v int) *UsageDetailUpsertOne {
+	return u.Update(func(s *UsageDetailUpsert) {
+		s.AddApp(v)
+	})
+}
+
+// UpdateApp sets the "app" field to the value that was provided on create.
+func (u *UsageDetailUpsertOne) UpdateApp() *UsageDetailUpsertOne {
+	return u.Update(func(s *UsageDetailUpsert) {
+		s.UpdateApp()
+	})
+}
+
+// ClearApp clears the value of the "app" field.
+func (u *UsageDetailUpsertOne) ClearApp() *UsageDetailUpsertOne {
+	return u.Update(func(s *UsageDetailUpsert) {
+		s.ClearApp()
+	})
+}
+
+// SetSessionID sets the "session_id" field.
+func (u *UsageDetailUpsertOne) SetSessionID(v uint64) *UsageDetailUpsertOne {
+	return u.Update(func(s *UsageDetailUpsert) {
+		s.SetSessionID(v)
+	})
+}
+
+// AddSessionID adds v to the "session_id" field.
+func (u *UsageDetailUpsertOne) AddSessionID(v uint64) *UsageDetailUpsertOne {
+	return u.Update(func(s *UsageDetailUpsert) {
+		s.AddSessionID(v)
+	})
+}
+
+// UpdateSessionID sets the "session_id" field to the value that was provided on create.
+func (u *UsageDetailUpsertOne) UpdateSessionID() *UsageDetailUpsertOne {
+	return u.Update(func(s *UsageDetailUpsert) {
+		s.UpdateSessionID()
+	})
+}
+
+// ClearSessionID clears the value of the "session_id" field.
+func (u *UsageDetailUpsertOne) ClearSessionID() *UsageDetailUpsertOne {
+	return u.Update(func(s *UsageDetailUpsert) {
+		s.ClearSessionID()
+	})
+}
+
+// SetRequest sets the "request" field.
+func (u *UsageDetailUpsertOne) SetRequest(v string) *UsageDetailUpsertOne {
+	return u.Update(func(s *UsageDetailUpsert) {
+		s.SetRequest(v)
+	})
+}
+
+// UpdateRequest sets the "request" field to the value that was provided on create.
+func (u *UsageDetailUpsertOne) UpdateRequest() *UsageDetailUpsertOne {
+	return u.Update(func(s *UsageDetailUpsert) {
+		s.UpdateRequest()
+	})
+}
+
+// SetResponse sets the "response" field.
+func (u *UsageDetailUpsertOne) SetResponse(v string) *UsageDetailUpsertOne {
+	return u.Update(func(s *UsageDetailUpsert) {
+		s.SetResponse(v)
+	})
+}
+
+// UpdateResponse sets the "response" field to the value that was provided on create.
+func (u *UsageDetailUpsertOne) UpdateResponse() *UsageDetailUpsertOne {
+	return u.Update(func(s *UsageDetailUpsert) {
+		s.UpdateResponse()
+	})
+}
+
+// SetTotalTokens sets the "total_tokens" field.
+func (u *UsageDetailUpsertOne) SetTotalTokens(v uint64) *UsageDetailUpsertOne {
+	return u.Update(func(s *UsageDetailUpsert) {
+		s.SetTotalTokens(v)
+	})
+}
+
+// AddTotalTokens adds v to the "total_tokens" field.
+func (u *UsageDetailUpsertOne) AddTotalTokens(v uint64) *UsageDetailUpsertOne {
+	return u.Update(func(s *UsageDetailUpsert) {
+		s.AddTotalTokens(v)
+	})
+}
+
+// UpdateTotalTokens sets the "total_tokens" field to the value that was provided on create.
+func (u *UsageDetailUpsertOne) UpdateTotalTokens() *UsageDetailUpsertOne {
+	return u.Update(func(s *UsageDetailUpsert) {
+		s.UpdateTotalTokens()
+	})
+}
+
+// ClearTotalTokens clears the value of the "total_tokens" field.
+func (u *UsageDetailUpsertOne) ClearTotalTokens() *UsageDetailUpsertOne {
+	return u.Update(func(s *UsageDetailUpsert) {
+		s.ClearTotalTokens()
+	})
+}
+
+// SetPromptTokens sets the "prompt_tokens" field.
+func (u *UsageDetailUpsertOne) SetPromptTokens(v uint64) *UsageDetailUpsertOne {
+	return u.Update(func(s *UsageDetailUpsert) {
+		s.SetPromptTokens(v)
+	})
+}
+
+// AddPromptTokens adds v to the "prompt_tokens" field.
+func (u *UsageDetailUpsertOne) AddPromptTokens(v uint64) *UsageDetailUpsertOne {
+	return u.Update(func(s *UsageDetailUpsert) {
+		s.AddPromptTokens(v)
+	})
+}
+
+// UpdatePromptTokens sets the "prompt_tokens" field to the value that was provided on create.
+func (u *UsageDetailUpsertOne) UpdatePromptTokens() *UsageDetailUpsertOne {
+	return u.Update(func(s *UsageDetailUpsert) {
+		s.UpdatePromptTokens()
+	})
+}
+
+// ClearPromptTokens clears the value of the "prompt_tokens" field.
+func (u *UsageDetailUpsertOne) ClearPromptTokens() *UsageDetailUpsertOne {
+	return u.Update(func(s *UsageDetailUpsert) {
+		s.ClearPromptTokens()
+	})
+}
+
+// SetCompletionTokens sets the "completion_tokens" field.
+func (u *UsageDetailUpsertOne) SetCompletionTokens(v uint64) *UsageDetailUpsertOne {
+	return u.Update(func(s *UsageDetailUpsert) {
+		s.SetCompletionTokens(v)
+	})
+}
+
+// AddCompletionTokens adds v to the "completion_tokens" field.
+func (u *UsageDetailUpsertOne) AddCompletionTokens(v uint64) *UsageDetailUpsertOne {
+	return u.Update(func(s *UsageDetailUpsert) {
+		s.AddCompletionTokens(v)
+	})
+}
+
+// UpdateCompletionTokens sets the "completion_tokens" field to the value that was provided on create.
+func (u *UsageDetailUpsertOne) UpdateCompletionTokens() *UsageDetailUpsertOne {
+	return u.Update(func(s *UsageDetailUpsert) {
+		s.UpdateCompletionTokens()
+	})
+}
+
+// ClearCompletionTokens clears the value of the "completion_tokens" field.
+func (u *UsageDetailUpsertOne) ClearCompletionTokens() *UsageDetailUpsertOne {
+	return u.Update(func(s *UsageDetailUpsert) {
+		s.ClearCompletionTokens()
+	})
+}
+
+// SetOrganizationID sets the "organization_id" field.
+func (u *UsageDetailUpsertOne) SetOrganizationID(v uint64) *UsageDetailUpsertOne {
+	return u.Update(func(s *UsageDetailUpsert) {
+		s.SetOrganizationID(v)
+	})
+}
+
+// AddOrganizationID adds v to the "organization_id" field.
+func (u *UsageDetailUpsertOne) AddOrganizationID(v uint64) *UsageDetailUpsertOne {
+	return u.Update(func(s *UsageDetailUpsert) {
+		s.AddOrganizationID(v)
+	})
+}
+
+// UpdateOrganizationID sets the "organization_id" field to the value that was provided on create.
+func (u *UsageDetailUpsertOne) UpdateOrganizationID() *UsageDetailUpsertOne {
+	return u.Update(func(s *UsageDetailUpsert) {
+		s.UpdateOrganizationID()
+	})
+}
+
+// ClearOrganizationID clears the value of the "organization_id" field.
+func (u *UsageDetailUpsertOne) ClearOrganizationID() *UsageDetailUpsertOne {
+	return u.Update(func(s *UsageDetailUpsert) {
+		s.ClearOrganizationID()
+	})
+}
+
+// Exec executes the query.
+func (u *UsageDetailUpsertOne) Exec(ctx context.Context) error {
+	if len(u.create.conflict) == 0 {
+		return errors.New("ent: missing options for UsageDetailCreate.OnConflict")
+	}
+	return u.create.Exec(ctx)
+}
+
+// ExecX is like Exec, but panics if an error occurs.
+func (u *UsageDetailUpsertOne) 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 *UsageDetailUpsertOne) ID(ctx context.Context) (id uint64, err error) {
+	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 *UsageDetailUpsertOne) IDX(ctx context.Context) uint64 {
+	id, err := u.ID(ctx)
+	if err != nil {
+		panic(err)
+	}
+	return id
+}
+
+// UsageDetailCreateBulk is the builder for creating many UsageDetail entities in bulk.
+type UsageDetailCreateBulk struct {
+	config
+	err      error
+	builders []*UsageDetailCreate
+	conflict []sql.ConflictOption
+}
+
+// Save creates the UsageDetail entities in the database.
+func (udcb *UsageDetailCreateBulk) Save(ctx context.Context) ([]*UsageDetail, error) {
+	if udcb.err != nil {
+		return nil, udcb.err
+	}
+	specs := make([]*sqlgraph.CreateSpec, len(udcb.builders))
+	nodes := make([]*UsageDetail, len(udcb.builders))
+	mutators := make([]Mutator, len(udcb.builders))
+	for i := range udcb.builders {
+		func(i int, root context.Context) {
+			builder := udcb.builders[i]
+			builder.defaults()
+			var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) {
+				mutation, ok := m.(*UsageDetailMutation)
+				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, udcb.builders[i+1].mutation)
+				} else {
+					spec := &sqlgraph.BatchCreateSpec{Nodes: specs}
+					spec.OnConflict = udcb.conflict
+					// Invoke the actual operation on the latest mutation in the chain.
+					if err = sqlgraph.BatchCreate(ctx, udcb.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
+				if specs[i].ID.Value != nil && nodes[i].ID == 0 {
+					id := specs[i].ID.Value.(int64)
+					nodes[i].ID = uint64(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, udcb.builders[0].mutation); err != nil {
+			return nil, err
+		}
+	}
+	return nodes, nil
+}
+
+// SaveX is like Save, but panics if an error occurs.
+func (udcb *UsageDetailCreateBulk) SaveX(ctx context.Context) []*UsageDetail {
+	v, err := udcb.Save(ctx)
+	if err != nil {
+		panic(err)
+	}
+	return v
+}
+
+// Exec executes the query.
+func (udcb *UsageDetailCreateBulk) Exec(ctx context.Context) error {
+	_, err := udcb.Save(ctx)
+	return err
+}
+
+// ExecX is like Exec, but panics if an error occurs.
+func (udcb *UsageDetailCreateBulk) ExecX(ctx context.Context) {
+	if err := udcb.Exec(ctx); err != nil {
+		panic(err)
+	}
+}
+
+// OnConflict allows configuring the `ON CONFLICT` / `ON DUPLICATE KEY` clause
+// of the `INSERT` statement. For example:
+//
+//	client.UsageDetail.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.UsageDetailUpsert) {
+//			SetCreatedAt(v+v).
+//		}).
+//		Exec(ctx)
+func (udcb *UsageDetailCreateBulk) OnConflict(opts ...sql.ConflictOption) *UsageDetailUpsertBulk {
+	udcb.conflict = opts
+	return &UsageDetailUpsertBulk{
+		create: udcb,
+	}
+}
+
+// OnConflictColumns calls `OnConflict` and configures the columns
+// as conflict target. Using this option is equivalent to using:
+//
+//	client.UsageDetail.Create().
+//		OnConflict(sql.ConflictColumns(columns...)).
+//		Exec(ctx)
+func (udcb *UsageDetailCreateBulk) OnConflictColumns(columns ...string) *UsageDetailUpsertBulk {
+	udcb.conflict = append(udcb.conflict, sql.ConflictColumns(columns...))
+	return &UsageDetailUpsertBulk{
+		create: udcb,
+	}
+}
+
+// UsageDetailUpsertBulk is the builder for "upsert"-ing
+// a bulk of UsageDetail nodes.
+type UsageDetailUpsertBulk struct {
+	create *UsageDetailCreateBulk
+}
+
+// UpdateNewValues updates the mutable fields using the new values that
+// were set on create. Using this option is equivalent to using:
+//
+//	client.UsageDetail.Create().
+//		OnConflict(
+//			sql.ResolveWithNewValues(),
+//			sql.ResolveWith(func(u *sql.UpdateSet) {
+//				u.SetIgnore(usagedetail.FieldID)
+//			}),
+//		).
+//		Exec(ctx)
+func (u *UsageDetailUpsertBulk) UpdateNewValues() *UsageDetailUpsertBulk {
+	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(usagedetail.FieldID)
+			}
+			if _, exists := b.mutation.CreatedAt(); exists {
+				s.SetIgnore(usagedetail.FieldCreatedAt)
+			}
+		}
+	}))
+	return u
+}
+
+// Ignore sets each column to itself in case of conflict.
+// Using this option is equivalent to using:
+//
+//	client.UsageDetail.Create().
+//		OnConflict(sql.ResolveWithIgnore()).
+//		Exec(ctx)
+func (u *UsageDetailUpsertBulk) Ignore() *UsageDetailUpsertBulk {
+	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 *UsageDetailUpsertBulk) DoNothing() *UsageDetailUpsertBulk {
+	u.create.conflict = append(u.create.conflict, sql.DoNothing())
+	return u
+}
+
+// Update allows overriding fields `UPDATE` values. See the UsageDetailCreateBulk.OnConflict
+// documentation for more info.
+func (u *UsageDetailUpsertBulk) Update(set func(*UsageDetailUpsert)) *UsageDetailUpsertBulk {
+	u.create.conflict = append(u.create.conflict, sql.ResolveWith(func(update *sql.UpdateSet) {
+		set(&UsageDetailUpsert{UpdateSet: update})
+	}))
+	return u
+}
+
+// SetUpdatedAt sets the "updated_at" field.
+func (u *UsageDetailUpsertBulk) SetUpdatedAt(v time.Time) *UsageDetailUpsertBulk {
+	return u.Update(func(s *UsageDetailUpsert) {
+		s.SetUpdatedAt(v)
+	})
+}
+
+// UpdateUpdatedAt sets the "updated_at" field to the value that was provided on create.
+func (u *UsageDetailUpsertBulk) UpdateUpdatedAt() *UsageDetailUpsertBulk {
+	return u.Update(func(s *UsageDetailUpsert) {
+		s.UpdateUpdatedAt()
+	})
+}
+
+// SetStatus sets the "status" field.
+func (u *UsageDetailUpsertBulk) SetStatus(v uint8) *UsageDetailUpsertBulk {
+	return u.Update(func(s *UsageDetailUpsert) {
+		s.SetStatus(v)
+	})
+}
+
+// AddStatus adds v to the "status" field.
+func (u *UsageDetailUpsertBulk) AddStatus(v uint8) *UsageDetailUpsertBulk {
+	return u.Update(func(s *UsageDetailUpsert) {
+		s.AddStatus(v)
+	})
+}
+
+// UpdateStatus sets the "status" field to the value that was provided on create.
+func (u *UsageDetailUpsertBulk) UpdateStatus() *UsageDetailUpsertBulk {
+	return u.Update(func(s *UsageDetailUpsert) {
+		s.UpdateStatus()
+	})
+}
+
+// ClearStatus clears the value of the "status" field.
+func (u *UsageDetailUpsertBulk) ClearStatus() *UsageDetailUpsertBulk {
+	return u.Update(func(s *UsageDetailUpsert) {
+		s.ClearStatus()
+	})
+}
+
+// SetType sets the "type" field.
+func (u *UsageDetailUpsertBulk) SetType(v int) *UsageDetailUpsertBulk {
+	return u.Update(func(s *UsageDetailUpsert) {
+		s.SetType(v)
+	})
+}
+
+// AddType adds v to the "type" field.
+func (u *UsageDetailUpsertBulk) AddType(v int) *UsageDetailUpsertBulk {
+	return u.Update(func(s *UsageDetailUpsert) {
+		s.AddType(v)
+	})
+}
+
+// UpdateType sets the "type" field to the value that was provided on create.
+func (u *UsageDetailUpsertBulk) UpdateType() *UsageDetailUpsertBulk {
+	return u.Update(func(s *UsageDetailUpsert) {
+		s.UpdateType()
+	})
+}
+
+// ClearType clears the value of the "type" field.
+func (u *UsageDetailUpsertBulk) ClearType() *UsageDetailUpsertBulk {
+	return u.Update(func(s *UsageDetailUpsert) {
+		s.ClearType()
+	})
+}
+
+// SetBotID sets the "bot_id" field.
+func (u *UsageDetailUpsertBulk) SetBotID(v string) *UsageDetailUpsertBulk {
+	return u.Update(func(s *UsageDetailUpsert) {
+		s.SetBotID(v)
+	})
+}
+
+// UpdateBotID sets the "bot_id" field to the value that was provided on create.
+func (u *UsageDetailUpsertBulk) UpdateBotID() *UsageDetailUpsertBulk {
+	return u.Update(func(s *UsageDetailUpsert) {
+		s.UpdateBotID()
+	})
+}
+
+// SetReceiverID sets the "receiver_id" field.
+func (u *UsageDetailUpsertBulk) SetReceiverID(v string) *UsageDetailUpsertBulk {
+	return u.Update(func(s *UsageDetailUpsert) {
+		s.SetReceiverID(v)
+	})
+}
+
+// UpdateReceiverID sets the "receiver_id" field to the value that was provided on create.
+func (u *UsageDetailUpsertBulk) UpdateReceiverID() *UsageDetailUpsertBulk {
+	return u.Update(func(s *UsageDetailUpsert) {
+		s.UpdateReceiverID()
+	})
+}
+
+// SetApp sets the "app" field.
+func (u *UsageDetailUpsertBulk) SetApp(v int) *UsageDetailUpsertBulk {
+	return u.Update(func(s *UsageDetailUpsert) {
+		s.SetApp(v)
+	})
+}
+
+// AddApp adds v to the "app" field.
+func (u *UsageDetailUpsertBulk) AddApp(v int) *UsageDetailUpsertBulk {
+	return u.Update(func(s *UsageDetailUpsert) {
+		s.AddApp(v)
+	})
+}
+
+// UpdateApp sets the "app" field to the value that was provided on create.
+func (u *UsageDetailUpsertBulk) UpdateApp() *UsageDetailUpsertBulk {
+	return u.Update(func(s *UsageDetailUpsert) {
+		s.UpdateApp()
+	})
+}
+
+// ClearApp clears the value of the "app" field.
+func (u *UsageDetailUpsertBulk) ClearApp() *UsageDetailUpsertBulk {
+	return u.Update(func(s *UsageDetailUpsert) {
+		s.ClearApp()
+	})
+}
+
+// SetSessionID sets the "session_id" field.
+func (u *UsageDetailUpsertBulk) SetSessionID(v uint64) *UsageDetailUpsertBulk {
+	return u.Update(func(s *UsageDetailUpsert) {
+		s.SetSessionID(v)
+	})
+}
+
+// AddSessionID adds v to the "session_id" field.
+func (u *UsageDetailUpsertBulk) AddSessionID(v uint64) *UsageDetailUpsertBulk {
+	return u.Update(func(s *UsageDetailUpsert) {
+		s.AddSessionID(v)
+	})
+}
+
+// UpdateSessionID sets the "session_id" field to the value that was provided on create.
+func (u *UsageDetailUpsertBulk) UpdateSessionID() *UsageDetailUpsertBulk {
+	return u.Update(func(s *UsageDetailUpsert) {
+		s.UpdateSessionID()
+	})
+}
+
+// ClearSessionID clears the value of the "session_id" field.
+func (u *UsageDetailUpsertBulk) ClearSessionID() *UsageDetailUpsertBulk {
+	return u.Update(func(s *UsageDetailUpsert) {
+		s.ClearSessionID()
+	})
+}
+
+// SetRequest sets the "request" field.
+func (u *UsageDetailUpsertBulk) SetRequest(v string) *UsageDetailUpsertBulk {
+	return u.Update(func(s *UsageDetailUpsert) {
+		s.SetRequest(v)
+	})
+}
+
+// UpdateRequest sets the "request" field to the value that was provided on create.
+func (u *UsageDetailUpsertBulk) UpdateRequest() *UsageDetailUpsertBulk {
+	return u.Update(func(s *UsageDetailUpsert) {
+		s.UpdateRequest()
+	})
+}
+
+// SetResponse sets the "response" field.
+func (u *UsageDetailUpsertBulk) SetResponse(v string) *UsageDetailUpsertBulk {
+	return u.Update(func(s *UsageDetailUpsert) {
+		s.SetResponse(v)
+	})
+}
+
+// UpdateResponse sets the "response" field to the value that was provided on create.
+func (u *UsageDetailUpsertBulk) UpdateResponse() *UsageDetailUpsertBulk {
+	return u.Update(func(s *UsageDetailUpsert) {
+		s.UpdateResponse()
+	})
+}
+
+// SetTotalTokens sets the "total_tokens" field.
+func (u *UsageDetailUpsertBulk) SetTotalTokens(v uint64) *UsageDetailUpsertBulk {
+	return u.Update(func(s *UsageDetailUpsert) {
+		s.SetTotalTokens(v)
+	})
+}
+
+// AddTotalTokens adds v to the "total_tokens" field.
+func (u *UsageDetailUpsertBulk) AddTotalTokens(v uint64) *UsageDetailUpsertBulk {
+	return u.Update(func(s *UsageDetailUpsert) {
+		s.AddTotalTokens(v)
+	})
+}
+
+// UpdateTotalTokens sets the "total_tokens" field to the value that was provided on create.
+func (u *UsageDetailUpsertBulk) UpdateTotalTokens() *UsageDetailUpsertBulk {
+	return u.Update(func(s *UsageDetailUpsert) {
+		s.UpdateTotalTokens()
+	})
+}
+
+// ClearTotalTokens clears the value of the "total_tokens" field.
+func (u *UsageDetailUpsertBulk) ClearTotalTokens() *UsageDetailUpsertBulk {
+	return u.Update(func(s *UsageDetailUpsert) {
+		s.ClearTotalTokens()
+	})
+}
+
+// SetPromptTokens sets the "prompt_tokens" field.
+func (u *UsageDetailUpsertBulk) SetPromptTokens(v uint64) *UsageDetailUpsertBulk {
+	return u.Update(func(s *UsageDetailUpsert) {
+		s.SetPromptTokens(v)
+	})
+}
+
+// AddPromptTokens adds v to the "prompt_tokens" field.
+func (u *UsageDetailUpsertBulk) AddPromptTokens(v uint64) *UsageDetailUpsertBulk {
+	return u.Update(func(s *UsageDetailUpsert) {
+		s.AddPromptTokens(v)
+	})
+}
+
+// UpdatePromptTokens sets the "prompt_tokens" field to the value that was provided on create.
+func (u *UsageDetailUpsertBulk) UpdatePromptTokens() *UsageDetailUpsertBulk {
+	return u.Update(func(s *UsageDetailUpsert) {
+		s.UpdatePromptTokens()
+	})
+}
+
+// ClearPromptTokens clears the value of the "prompt_tokens" field.
+func (u *UsageDetailUpsertBulk) ClearPromptTokens() *UsageDetailUpsertBulk {
+	return u.Update(func(s *UsageDetailUpsert) {
+		s.ClearPromptTokens()
+	})
+}
+
+// SetCompletionTokens sets the "completion_tokens" field.
+func (u *UsageDetailUpsertBulk) SetCompletionTokens(v uint64) *UsageDetailUpsertBulk {
+	return u.Update(func(s *UsageDetailUpsert) {
+		s.SetCompletionTokens(v)
+	})
+}
+
+// AddCompletionTokens adds v to the "completion_tokens" field.
+func (u *UsageDetailUpsertBulk) AddCompletionTokens(v uint64) *UsageDetailUpsertBulk {
+	return u.Update(func(s *UsageDetailUpsert) {
+		s.AddCompletionTokens(v)
+	})
+}
+
+// UpdateCompletionTokens sets the "completion_tokens" field to the value that was provided on create.
+func (u *UsageDetailUpsertBulk) UpdateCompletionTokens() *UsageDetailUpsertBulk {
+	return u.Update(func(s *UsageDetailUpsert) {
+		s.UpdateCompletionTokens()
+	})
+}
+
+// ClearCompletionTokens clears the value of the "completion_tokens" field.
+func (u *UsageDetailUpsertBulk) ClearCompletionTokens() *UsageDetailUpsertBulk {
+	return u.Update(func(s *UsageDetailUpsert) {
+		s.ClearCompletionTokens()
+	})
+}
+
+// SetOrganizationID sets the "organization_id" field.
+func (u *UsageDetailUpsertBulk) SetOrganizationID(v uint64) *UsageDetailUpsertBulk {
+	return u.Update(func(s *UsageDetailUpsert) {
+		s.SetOrganizationID(v)
+	})
+}
+
+// AddOrganizationID adds v to the "organization_id" field.
+func (u *UsageDetailUpsertBulk) AddOrganizationID(v uint64) *UsageDetailUpsertBulk {
+	return u.Update(func(s *UsageDetailUpsert) {
+		s.AddOrganizationID(v)
+	})
+}
+
+// UpdateOrganizationID sets the "organization_id" field to the value that was provided on create.
+func (u *UsageDetailUpsertBulk) UpdateOrganizationID() *UsageDetailUpsertBulk {
+	return u.Update(func(s *UsageDetailUpsert) {
+		s.UpdateOrganizationID()
+	})
+}
+
+// ClearOrganizationID clears the value of the "organization_id" field.
+func (u *UsageDetailUpsertBulk) ClearOrganizationID() *UsageDetailUpsertBulk {
+	return u.Update(func(s *UsageDetailUpsert) {
+		s.ClearOrganizationID()
+	})
+}
+
+// Exec executes the query.
+func (u *UsageDetailUpsertBulk) 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 UsageDetailCreateBulk instead", i)
+		}
+	}
+	if len(u.create.conflict) == 0 {
+		return errors.New("ent: missing options for UsageDetailCreateBulk.OnConflict")
+	}
+	return u.create.Exec(ctx)
+}
+
+// ExecX is like Exec, but panics if an error occurs.
+func (u *UsageDetailUpsertBulk) ExecX(ctx context.Context) {
+	if err := u.create.Exec(ctx); err != nil {
+		panic(err)
+	}
+}

+ 88 - 0
ent/usagedetail_delete.go

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

+ 526 - 0
ent/usagedetail_query.go

@@ -0,0 +1,526 @@
+// Code generated by ent, DO NOT EDIT.
+
+package ent
+
+import (
+	"context"
+	"fmt"
+	"math"
+	"wechat-api/ent/predicate"
+	"wechat-api/ent/usagedetail"
+
+	"entgo.io/ent/dialect/sql"
+	"entgo.io/ent/dialect/sql/sqlgraph"
+	"entgo.io/ent/schema/field"
+)
+
+// UsageDetailQuery is the builder for querying UsageDetail entities.
+type UsageDetailQuery struct {
+	config
+	ctx        *QueryContext
+	order      []usagedetail.OrderOption
+	inters     []Interceptor
+	predicates []predicate.UsageDetail
+	// intermediate query (i.e. traversal path).
+	sql  *sql.Selector
+	path func(context.Context) (*sql.Selector, error)
+}
+
+// Where adds a new predicate for the UsageDetailQuery builder.
+func (udq *UsageDetailQuery) Where(ps ...predicate.UsageDetail) *UsageDetailQuery {
+	udq.predicates = append(udq.predicates, ps...)
+	return udq
+}
+
+// Limit the number of records to be returned by this query.
+func (udq *UsageDetailQuery) Limit(limit int) *UsageDetailQuery {
+	udq.ctx.Limit = &limit
+	return udq
+}
+
+// Offset to start from.
+func (udq *UsageDetailQuery) Offset(offset int) *UsageDetailQuery {
+	udq.ctx.Offset = &offset
+	return udq
+}
+
+// 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 (udq *UsageDetailQuery) Unique(unique bool) *UsageDetailQuery {
+	udq.ctx.Unique = &unique
+	return udq
+}
+
+// Order specifies how the records should be ordered.
+func (udq *UsageDetailQuery) Order(o ...usagedetail.OrderOption) *UsageDetailQuery {
+	udq.order = append(udq.order, o...)
+	return udq
+}
+
+// First returns the first UsageDetail entity from the query.
+// Returns a *NotFoundError when no UsageDetail was found.
+func (udq *UsageDetailQuery) First(ctx context.Context) (*UsageDetail, error) {
+	nodes, err := udq.Limit(1).All(setContextOp(ctx, udq.ctx, "First"))
+	if err != nil {
+		return nil, err
+	}
+	if len(nodes) == 0 {
+		return nil, &NotFoundError{usagedetail.Label}
+	}
+	return nodes[0], nil
+}
+
+// FirstX is like First, but panics if an error occurs.
+func (udq *UsageDetailQuery) FirstX(ctx context.Context) *UsageDetail {
+	node, err := udq.First(ctx)
+	if err != nil && !IsNotFound(err) {
+		panic(err)
+	}
+	return node
+}
+
+// FirstID returns the first UsageDetail ID from the query.
+// Returns a *NotFoundError when no UsageDetail ID was found.
+func (udq *UsageDetailQuery) FirstID(ctx context.Context) (id uint64, err error) {
+	var ids []uint64
+	if ids, err = udq.Limit(1).IDs(setContextOp(ctx, udq.ctx, "FirstID")); err != nil {
+		return
+	}
+	if len(ids) == 0 {
+		err = &NotFoundError{usagedetail.Label}
+		return
+	}
+	return ids[0], nil
+}
+
+// FirstIDX is like FirstID, but panics if an error occurs.
+func (udq *UsageDetailQuery) FirstIDX(ctx context.Context) uint64 {
+	id, err := udq.FirstID(ctx)
+	if err != nil && !IsNotFound(err) {
+		panic(err)
+	}
+	return id
+}
+
+// Only returns a single UsageDetail entity found by the query, ensuring it only returns one.
+// Returns a *NotSingularError when more than one UsageDetail entity is found.
+// Returns a *NotFoundError when no UsageDetail entities are found.
+func (udq *UsageDetailQuery) Only(ctx context.Context) (*UsageDetail, error) {
+	nodes, err := udq.Limit(2).All(setContextOp(ctx, udq.ctx, "Only"))
+	if err != nil {
+		return nil, err
+	}
+	switch len(nodes) {
+	case 1:
+		return nodes[0], nil
+	case 0:
+		return nil, &NotFoundError{usagedetail.Label}
+	default:
+		return nil, &NotSingularError{usagedetail.Label}
+	}
+}
+
+// OnlyX is like Only, but panics if an error occurs.
+func (udq *UsageDetailQuery) OnlyX(ctx context.Context) *UsageDetail {
+	node, err := udq.Only(ctx)
+	if err != nil {
+		panic(err)
+	}
+	return node
+}
+
+// OnlyID is like Only, but returns the only UsageDetail ID in the query.
+// Returns a *NotSingularError when more than one UsageDetail ID is found.
+// Returns a *NotFoundError when no entities are found.
+func (udq *UsageDetailQuery) OnlyID(ctx context.Context) (id uint64, err error) {
+	var ids []uint64
+	if ids, err = udq.Limit(2).IDs(setContextOp(ctx, udq.ctx, "OnlyID")); err != nil {
+		return
+	}
+	switch len(ids) {
+	case 1:
+		id = ids[0]
+	case 0:
+		err = &NotFoundError{usagedetail.Label}
+	default:
+		err = &NotSingularError{usagedetail.Label}
+	}
+	return
+}
+
+// OnlyIDX is like OnlyID, but panics if an error occurs.
+func (udq *UsageDetailQuery) OnlyIDX(ctx context.Context) uint64 {
+	id, err := udq.OnlyID(ctx)
+	if err != nil {
+		panic(err)
+	}
+	return id
+}
+
+// All executes the query and returns a list of UsageDetails.
+func (udq *UsageDetailQuery) All(ctx context.Context) ([]*UsageDetail, error) {
+	ctx = setContextOp(ctx, udq.ctx, "All")
+	if err := udq.prepareQuery(ctx); err != nil {
+		return nil, err
+	}
+	qr := querierAll[[]*UsageDetail, *UsageDetailQuery]()
+	return withInterceptors[[]*UsageDetail](ctx, udq, qr, udq.inters)
+}
+
+// AllX is like All, but panics if an error occurs.
+func (udq *UsageDetailQuery) AllX(ctx context.Context) []*UsageDetail {
+	nodes, err := udq.All(ctx)
+	if err != nil {
+		panic(err)
+	}
+	return nodes
+}
+
+// IDs executes the query and returns a list of UsageDetail IDs.
+func (udq *UsageDetailQuery) IDs(ctx context.Context) (ids []uint64, err error) {
+	if udq.ctx.Unique == nil && udq.path != nil {
+		udq.Unique(true)
+	}
+	ctx = setContextOp(ctx, udq.ctx, "IDs")
+	if err = udq.Select(usagedetail.FieldID).Scan(ctx, &ids); err != nil {
+		return nil, err
+	}
+	return ids, nil
+}
+
+// IDsX is like IDs, but panics if an error occurs.
+func (udq *UsageDetailQuery) IDsX(ctx context.Context) []uint64 {
+	ids, err := udq.IDs(ctx)
+	if err != nil {
+		panic(err)
+	}
+	return ids
+}
+
+// Count returns the count of the given query.
+func (udq *UsageDetailQuery) Count(ctx context.Context) (int, error) {
+	ctx = setContextOp(ctx, udq.ctx, "Count")
+	if err := udq.prepareQuery(ctx); err != nil {
+		return 0, err
+	}
+	return withInterceptors[int](ctx, udq, querierCount[*UsageDetailQuery](), udq.inters)
+}
+
+// CountX is like Count, but panics if an error occurs.
+func (udq *UsageDetailQuery) CountX(ctx context.Context) int {
+	count, err := udq.Count(ctx)
+	if err != nil {
+		panic(err)
+	}
+	return count
+}
+
+// Exist returns true if the query has elements in the graph.
+func (udq *UsageDetailQuery) Exist(ctx context.Context) (bool, error) {
+	ctx = setContextOp(ctx, udq.ctx, "Exist")
+	switch _, err := udq.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 (udq *UsageDetailQuery) ExistX(ctx context.Context) bool {
+	exist, err := udq.Exist(ctx)
+	if err != nil {
+		panic(err)
+	}
+	return exist
+}
+
+// Clone returns a duplicate of the UsageDetailQuery builder, including all associated steps. It can be
+// used to prepare common query builders and use them differently after the clone is made.
+func (udq *UsageDetailQuery) Clone() *UsageDetailQuery {
+	if udq == nil {
+		return nil
+	}
+	return &UsageDetailQuery{
+		config:     udq.config,
+		ctx:        udq.ctx.Clone(),
+		order:      append([]usagedetail.OrderOption{}, udq.order...),
+		inters:     append([]Interceptor{}, udq.inters...),
+		predicates: append([]predicate.UsageDetail{}, udq.predicates...),
+		// clone intermediate query.
+		sql:  udq.sql.Clone(),
+		path: udq.path,
+	}
+}
+
+// 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 {
+//		CreatedAt time.Time `json:"created_at,omitempty"`
+//		Count int `json:"count,omitempty"`
+//	}
+//
+//	client.UsageDetail.Query().
+//		GroupBy(usagedetail.FieldCreatedAt).
+//		Aggregate(ent.Count()).
+//		Scan(ctx, &v)
+func (udq *UsageDetailQuery) GroupBy(field string, fields ...string) *UsageDetailGroupBy {
+	udq.ctx.Fields = append([]string{field}, fields...)
+	grbuild := &UsageDetailGroupBy{build: udq}
+	grbuild.flds = &udq.ctx.Fields
+	grbuild.label = usagedetail.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 {
+//		CreatedAt time.Time `json:"created_at,omitempty"`
+//	}
+//
+//	client.UsageDetail.Query().
+//		Select(usagedetail.FieldCreatedAt).
+//		Scan(ctx, &v)
+func (udq *UsageDetailQuery) Select(fields ...string) *UsageDetailSelect {
+	udq.ctx.Fields = append(udq.ctx.Fields, fields...)
+	sbuild := &UsageDetailSelect{UsageDetailQuery: udq}
+	sbuild.label = usagedetail.Label
+	sbuild.flds, sbuild.scan = &udq.ctx.Fields, sbuild.Scan
+	return sbuild
+}
+
+// Aggregate returns a UsageDetailSelect configured with the given aggregations.
+func (udq *UsageDetailQuery) Aggregate(fns ...AggregateFunc) *UsageDetailSelect {
+	return udq.Select().Aggregate(fns...)
+}
+
+func (udq *UsageDetailQuery) prepareQuery(ctx context.Context) error {
+	for _, inter := range udq.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, udq); err != nil {
+				return err
+			}
+		}
+	}
+	for _, f := range udq.ctx.Fields {
+		if !usagedetail.ValidColumn(f) {
+			return &ValidationError{Name: f, err: fmt.Errorf("ent: invalid field %q for query", f)}
+		}
+	}
+	if udq.path != nil {
+		prev, err := udq.path(ctx)
+		if err != nil {
+			return err
+		}
+		udq.sql = prev
+	}
+	return nil
+}
+
+func (udq *UsageDetailQuery) sqlAll(ctx context.Context, hooks ...queryHook) ([]*UsageDetail, error) {
+	var (
+		nodes = []*UsageDetail{}
+		_spec = udq.querySpec()
+	)
+	_spec.ScanValues = func(columns []string) ([]any, error) {
+		return (*UsageDetail).scanValues(nil, columns)
+	}
+	_spec.Assign = func(columns []string, values []any) error {
+		node := &UsageDetail{config: udq.config}
+		nodes = append(nodes, node)
+		return node.assignValues(columns, values)
+	}
+	for i := range hooks {
+		hooks[i](ctx, _spec)
+	}
+	if err := sqlgraph.QueryNodes(ctx, udq.driver, _spec); err != nil {
+		return nil, err
+	}
+	if len(nodes) == 0 {
+		return nodes, nil
+	}
+	return nodes, nil
+}
+
+func (udq *UsageDetailQuery) sqlCount(ctx context.Context) (int, error) {
+	_spec := udq.querySpec()
+	_spec.Node.Columns = udq.ctx.Fields
+	if len(udq.ctx.Fields) > 0 {
+		_spec.Unique = udq.ctx.Unique != nil && *udq.ctx.Unique
+	}
+	return sqlgraph.CountNodes(ctx, udq.driver, _spec)
+}
+
+func (udq *UsageDetailQuery) querySpec() *sqlgraph.QuerySpec {
+	_spec := sqlgraph.NewQuerySpec(usagedetail.Table, usagedetail.Columns, sqlgraph.NewFieldSpec(usagedetail.FieldID, field.TypeUint64))
+	_spec.From = udq.sql
+	if unique := udq.ctx.Unique; unique != nil {
+		_spec.Unique = *unique
+	} else if udq.path != nil {
+		_spec.Unique = true
+	}
+	if fields := udq.ctx.Fields; len(fields) > 0 {
+		_spec.Node.Columns = make([]string, 0, len(fields))
+		_spec.Node.Columns = append(_spec.Node.Columns, usagedetail.FieldID)
+		for i := range fields {
+			if fields[i] != usagedetail.FieldID {
+				_spec.Node.Columns = append(_spec.Node.Columns, fields[i])
+			}
+		}
+	}
+	if ps := udq.predicates; len(ps) > 0 {
+		_spec.Predicate = func(selector *sql.Selector) {
+			for i := range ps {
+				ps[i](selector)
+			}
+		}
+	}
+	if limit := udq.ctx.Limit; limit != nil {
+		_spec.Limit = *limit
+	}
+	if offset := udq.ctx.Offset; offset != nil {
+		_spec.Offset = *offset
+	}
+	if ps := udq.order; len(ps) > 0 {
+		_spec.Order = func(selector *sql.Selector) {
+			for i := range ps {
+				ps[i](selector)
+			}
+		}
+	}
+	return _spec
+}
+
+func (udq *UsageDetailQuery) sqlQuery(ctx context.Context) *sql.Selector {
+	builder := sql.Dialect(udq.driver.Dialect())
+	t1 := builder.Table(usagedetail.Table)
+	columns := udq.ctx.Fields
+	if len(columns) == 0 {
+		columns = usagedetail.Columns
+	}
+	selector := builder.Select(t1.Columns(columns...)...).From(t1)
+	if udq.sql != nil {
+		selector = udq.sql
+		selector.Select(selector.Columns(columns...)...)
+	}
+	if udq.ctx.Unique != nil && *udq.ctx.Unique {
+		selector.Distinct()
+	}
+	for _, p := range udq.predicates {
+		p(selector)
+	}
+	for _, p := range udq.order {
+		p(selector)
+	}
+	if offset := udq.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 := udq.ctx.Limit; limit != nil {
+		selector.Limit(*limit)
+	}
+	return selector
+}
+
+// UsageDetailGroupBy is the group-by builder for UsageDetail entities.
+type UsageDetailGroupBy struct {
+	selector
+	build *UsageDetailQuery
+}
+
+// Aggregate adds the given aggregation functions to the group-by query.
+func (udgb *UsageDetailGroupBy) Aggregate(fns ...AggregateFunc) *UsageDetailGroupBy {
+	udgb.fns = append(udgb.fns, fns...)
+	return udgb
+}
+
+// Scan applies the selector query and scans the result into the given value.
+func (udgb *UsageDetailGroupBy) Scan(ctx context.Context, v any) error {
+	ctx = setContextOp(ctx, udgb.build.ctx, "GroupBy")
+	if err := udgb.build.prepareQuery(ctx); err != nil {
+		return err
+	}
+	return scanWithInterceptors[*UsageDetailQuery, *UsageDetailGroupBy](ctx, udgb.build, udgb, udgb.build.inters, v)
+}
+
+func (udgb *UsageDetailGroupBy) sqlScan(ctx context.Context, root *UsageDetailQuery, v any) error {
+	selector := root.sqlQuery(ctx).Select()
+	aggregation := make([]string, 0, len(udgb.fns))
+	for _, fn := range udgb.fns {
+		aggregation = append(aggregation, fn(selector))
+	}
+	if len(selector.SelectedColumns()) == 0 {
+		columns := make([]string, 0, len(*udgb.flds)+len(udgb.fns))
+		for _, f := range *udgb.flds {
+			columns = append(columns, selector.C(f))
+		}
+		columns = append(columns, aggregation...)
+		selector.Select(columns...)
+	}
+	selector.GroupBy(selector.Columns(*udgb.flds...)...)
+	if err := selector.Err(); err != nil {
+		return err
+	}
+	rows := &sql.Rows{}
+	query, args := selector.Query()
+	if err := udgb.build.driver.Query(ctx, query, args, rows); err != nil {
+		return err
+	}
+	defer rows.Close()
+	return sql.ScanSlice(rows, v)
+}
+
+// UsageDetailSelect is the builder for selecting fields of UsageDetail entities.
+type UsageDetailSelect struct {
+	*UsageDetailQuery
+	selector
+}
+
+// Aggregate adds the given aggregation functions to the selector query.
+func (uds *UsageDetailSelect) Aggregate(fns ...AggregateFunc) *UsageDetailSelect {
+	uds.fns = append(uds.fns, fns...)
+	return uds
+}
+
+// Scan applies the selector query and scans the result into the given value.
+func (uds *UsageDetailSelect) Scan(ctx context.Context, v any) error {
+	ctx = setContextOp(ctx, uds.ctx, "Select")
+	if err := uds.prepareQuery(ctx); err != nil {
+		return err
+	}
+	return scanWithInterceptors[*UsageDetailQuery, *UsageDetailSelect](ctx, uds.UsageDetailQuery, uds, uds.inters, v)
+}
+
+func (uds *UsageDetailSelect) sqlScan(ctx context.Context, root *UsageDetailQuery, v any) error {
+	selector := root.sqlQuery(ctx)
+	aggregation := make([]string, 0, len(uds.fns))
+	for _, fn := range uds.fns {
+		aggregation = append(aggregation, fn(selector))
+	}
+	switch n := len(*uds.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 := uds.driver.Query(ctx, query, args, rows); err != nil {
+		return err
+	}
+	defer rows.Close()
+	return sql.ScanSlice(rows, v)
+}

+ 924 - 0
ent/usagedetail_update.go

@@ -0,0 +1,924 @@
+// Code generated by ent, DO NOT EDIT.
+
+package ent
+
+import (
+	"context"
+	"errors"
+	"fmt"
+	"time"
+	"wechat-api/ent/predicate"
+	"wechat-api/ent/usagedetail"
+
+	"entgo.io/ent/dialect/sql"
+	"entgo.io/ent/dialect/sql/sqlgraph"
+	"entgo.io/ent/schema/field"
+)
+
+// UsageDetailUpdate is the builder for updating UsageDetail entities.
+type UsageDetailUpdate struct {
+	config
+	hooks    []Hook
+	mutation *UsageDetailMutation
+}
+
+// Where appends a list predicates to the UsageDetailUpdate builder.
+func (udu *UsageDetailUpdate) Where(ps ...predicate.UsageDetail) *UsageDetailUpdate {
+	udu.mutation.Where(ps...)
+	return udu
+}
+
+// SetUpdatedAt sets the "updated_at" field.
+func (udu *UsageDetailUpdate) SetUpdatedAt(t time.Time) *UsageDetailUpdate {
+	udu.mutation.SetUpdatedAt(t)
+	return udu
+}
+
+// SetStatus sets the "status" field.
+func (udu *UsageDetailUpdate) SetStatus(u uint8) *UsageDetailUpdate {
+	udu.mutation.ResetStatus()
+	udu.mutation.SetStatus(u)
+	return udu
+}
+
+// SetNillableStatus sets the "status" field if the given value is not nil.
+func (udu *UsageDetailUpdate) SetNillableStatus(u *uint8) *UsageDetailUpdate {
+	if u != nil {
+		udu.SetStatus(*u)
+	}
+	return udu
+}
+
+// AddStatus adds u to the "status" field.
+func (udu *UsageDetailUpdate) AddStatus(u int8) *UsageDetailUpdate {
+	udu.mutation.AddStatus(u)
+	return udu
+}
+
+// ClearStatus clears the value of the "status" field.
+func (udu *UsageDetailUpdate) ClearStatus() *UsageDetailUpdate {
+	udu.mutation.ClearStatus()
+	return udu
+}
+
+// SetType sets the "type" field.
+func (udu *UsageDetailUpdate) SetType(i int) *UsageDetailUpdate {
+	udu.mutation.ResetType()
+	udu.mutation.SetType(i)
+	return udu
+}
+
+// SetNillableType sets the "type" field if the given value is not nil.
+func (udu *UsageDetailUpdate) SetNillableType(i *int) *UsageDetailUpdate {
+	if i != nil {
+		udu.SetType(*i)
+	}
+	return udu
+}
+
+// AddType adds i to the "type" field.
+func (udu *UsageDetailUpdate) AddType(i int) *UsageDetailUpdate {
+	udu.mutation.AddType(i)
+	return udu
+}
+
+// ClearType clears the value of the "type" field.
+func (udu *UsageDetailUpdate) ClearType() *UsageDetailUpdate {
+	udu.mutation.ClearType()
+	return udu
+}
+
+// SetBotID sets the "bot_id" field.
+func (udu *UsageDetailUpdate) SetBotID(s string) *UsageDetailUpdate {
+	udu.mutation.SetBotID(s)
+	return udu
+}
+
+// SetNillableBotID sets the "bot_id" field if the given value is not nil.
+func (udu *UsageDetailUpdate) SetNillableBotID(s *string) *UsageDetailUpdate {
+	if s != nil {
+		udu.SetBotID(*s)
+	}
+	return udu
+}
+
+// SetReceiverID sets the "receiver_id" field.
+func (udu *UsageDetailUpdate) SetReceiverID(s string) *UsageDetailUpdate {
+	udu.mutation.SetReceiverID(s)
+	return udu
+}
+
+// SetNillableReceiverID sets the "receiver_id" field if the given value is not nil.
+func (udu *UsageDetailUpdate) SetNillableReceiverID(s *string) *UsageDetailUpdate {
+	if s != nil {
+		udu.SetReceiverID(*s)
+	}
+	return udu
+}
+
+// SetApp sets the "app" field.
+func (udu *UsageDetailUpdate) SetApp(i int) *UsageDetailUpdate {
+	udu.mutation.ResetApp()
+	udu.mutation.SetApp(i)
+	return udu
+}
+
+// SetNillableApp sets the "app" field if the given value is not nil.
+func (udu *UsageDetailUpdate) SetNillableApp(i *int) *UsageDetailUpdate {
+	if i != nil {
+		udu.SetApp(*i)
+	}
+	return udu
+}
+
+// AddApp adds i to the "app" field.
+func (udu *UsageDetailUpdate) AddApp(i int) *UsageDetailUpdate {
+	udu.mutation.AddApp(i)
+	return udu
+}
+
+// ClearApp clears the value of the "app" field.
+func (udu *UsageDetailUpdate) ClearApp() *UsageDetailUpdate {
+	udu.mutation.ClearApp()
+	return udu
+}
+
+// SetSessionID sets the "session_id" field.
+func (udu *UsageDetailUpdate) SetSessionID(u uint64) *UsageDetailUpdate {
+	udu.mutation.ResetSessionID()
+	udu.mutation.SetSessionID(u)
+	return udu
+}
+
+// SetNillableSessionID sets the "session_id" field if the given value is not nil.
+func (udu *UsageDetailUpdate) SetNillableSessionID(u *uint64) *UsageDetailUpdate {
+	if u != nil {
+		udu.SetSessionID(*u)
+	}
+	return udu
+}
+
+// AddSessionID adds u to the "session_id" field.
+func (udu *UsageDetailUpdate) AddSessionID(u int64) *UsageDetailUpdate {
+	udu.mutation.AddSessionID(u)
+	return udu
+}
+
+// ClearSessionID clears the value of the "session_id" field.
+func (udu *UsageDetailUpdate) ClearSessionID() *UsageDetailUpdate {
+	udu.mutation.ClearSessionID()
+	return udu
+}
+
+// SetRequest sets the "request" field.
+func (udu *UsageDetailUpdate) SetRequest(s string) *UsageDetailUpdate {
+	udu.mutation.SetRequest(s)
+	return udu
+}
+
+// SetNillableRequest sets the "request" field if the given value is not nil.
+func (udu *UsageDetailUpdate) SetNillableRequest(s *string) *UsageDetailUpdate {
+	if s != nil {
+		udu.SetRequest(*s)
+	}
+	return udu
+}
+
+// SetResponse sets the "response" field.
+func (udu *UsageDetailUpdate) SetResponse(s string) *UsageDetailUpdate {
+	udu.mutation.SetResponse(s)
+	return udu
+}
+
+// SetNillableResponse sets the "response" field if the given value is not nil.
+func (udu *UsageDetailUpdate) SetNillableResponse(s *string) *UsageDetailUpdate {
+	if s != nil {
+		udu.SetResponse(*s)
+	}
+	return udu
+}
+
+// SetTotalTokens sets the "total_tokens" field.
+func (udu *UsageDetailUpdate) SetTotalTokens(u uint64) *UsageDetailUpdate {
+	udu.mutation.ResetTotalTokens()
+	udu.mutation.SetTotalTokens(u)
+	return udu
+}
+
+// SetNillableTotalTokens sets the "total_tokens" field if the given value is not nil.
+func (udu *UsageDetailUpdate) SetNillableTotalTokens(u *uint64) *UsageDetailUpdate {
+	if u != nil {
+		udu.SetTotalTokens(*u)
+	}
+	return udu
+}
+
+// AddTotalTokens adds u to the "total_tokens" field.
+func (udu *UsageDetailUpdate) AddTotalTokens(u int64) *UsageDetailUpdate {
+	udu.mutation.AddTotalTokens(u)
+	return udu
+}
+
+// ClearTotalTokens clears the value of the "total_tokens" field.
+func (udu *UsageDetailUpdate) ClearTotalTokens() *UsageDetailUpdate {
+	udu.mutation.ClearTotalTokens()
+	return udu
+}
+
+// SetPromptTokens sets the "prompt_tokens" field.
+func (udu *UsageDetailUpdate) SetPromptTokens(u uint64) *UsageDetailUpdate {
+	udu.mutation.ResetPromptTokens()
+	udu.mutation.SetPromptTokens(u)
+	return udu
+}
+
+// SetNillablePromptTokens sets the "prompt_tokens" field if the given value is not nil.
+func (udu *UsageDetailUpdate) SetNillablePromptTokens(u *uint64) *UsageDetailUpdate {
+	if u != nil {
+		udu.SetPromptTokens(*u)
+	}
+	return udu
+}
+
+// AddPromptTokens adds u to the "prompt_tokens" field.
+func (udu *UsageDetailUpdate) AddPromptTokens(u int64) *UsageDetailUpdate {
+	udu.mutation.AddPromptTokens(u)
+	return udu
+}
+
+// ClearPromptTokens clears the value of the "prompt_tokens" field.
+func (udu *UsageDetailUpdate) ClearPromptTokens() *UsageDetailUpdate {
+	udu.mutation.ClearPromptTokens()
+	return udu
+}
+
+// SetCompletionTokens sets the "completion_tokens" field.
+func (udu *UsageDetailUpdate) SetCompletionTokens(u uint64) *UsageDetailUpdate {
+	udu.mutation.ResetCompletionTokens()
+	udu.mutation.SetCompletionTokens(u)
+	return udu
+}
+
+// SetNillableCompletionTokens sets the "completion_tokens" field if the given value is not nil.
+func (udu *UsageDetailUpdate) SetNillableCompletionTokens(u *uint64) *UsageDetailUpdate {
+	if u != nil {
+		udu.SetCompletionTokens(*u)
+	}
+	return udu
+}
+
+// AddCompletionTokens adds u to the "completion_tokens" field.
+func (udu *UsageDetailUpdate) AddCompletionTokens(u int64) *UsageDetailUpdate {
+	udu.mutation.AddCompletionTokens(u)
+	return udu
+}
+
+// ClearCompletionTokens clears the value of the "completion_tokens" field.
+func (udu *UsageDetailUpdate) ClearCompletionTokens() *UsageDetailUpdate {
+	udu.mutation.ClearCompletionTokens()
+	return udu
+}
+
+// SetOrganizationID sets the "organization_id" field.
+func (udu *UsageDetailUpdate) SetOrganizationID(u uint64) *UsageDetailUpdate {
+	udu.mutation.ResetOrganizationID()
+	udu.mutation.SetOrganizationID(u)
+	return udu
+}
+
+// SetNillableOrganizationID sets the "organization_id" field if the given value is not nil.
+func (udu *UsageDetailUpdate) SetNillableOrganizationID(u *uint64) *UsageDetailUpdate {
+	if u != nil {
+		udu.SetOrganizationID(*u)
+	}
+	return udu
+}
+
+// AddOrganizationID adds u to the "organization_id" field.
+func (udu *UsageDetailUpdate) AddOrganizationID(u int64) *UsageDetailUpdate {
+	udu.mutation.AddOrganizationID(u)
+	return udu
+}
+
+// ClearOrganizationID clears the value of the "organization_id" field.
+func (udu *UsageDetailUpdate) ClearOrganizationID() *UsageDetailUpdate {
+	udu.mutation.ClearOrganizationID()
+	return udu
+}
+
+// Mutation returns the UsageDetailMutation object of the builder.
+func (udu *UsageDetailUpdate) Mutation() *UsageDetailMutation {
+	return udu.mutation
+}
+
+// Save executes the query and returns the number of nodes affected by the update operation.
+func (udu *UsageDetailUpdate) Save(ctx context.Context) (int, error) {
+	udu.defaults()
+	return withHooks(ctx, udu.sqlSave, udu.mutation, udu.hooks)
+}
+
+// SaveX is like Save, but panics if an error occurs.
+func (udu *UsageDetailUpdate) SaveX(ctx context.Context) int {
+	affected, err := udu.Save(ctx)
+	if err != nil {
+		panic(err)
+	}
+	return affected
+}
+
+// Exec executes the query.
+func (udu *UsageDetailUpdate) Exec(ctx context.Context) error {
+	_, err := udu.Save(ctx)
+	return err
+}
+
+// ExecX is like Exec, but panics if an error occurs.
+func (udu *UsageDetailUpdate) ExecX(ctx context.Context) {
+	if err := udu.Exec(ctx); err != nil {
+		panic(err)
+	}
+}
+
+// defaults sets the default values of the builder before save.
+func (udu *UsageDetailUpdate) defaults() {
+	if _, ok := udu.mutation.UpdatedAt(); !ok {
+		v := usagedetail.UpdateDefaultUpdatedAt()
+		udu.mutation.SetUpdatedAt(v)
+	}
+}
+
+func (udu *UsageDetailUpdate) sqlSave(ctx context.Context) (n int, err error) {
+	_spec := sqlgraph.NewUpdateSpec(usagedetail.Table, usagedetail.Columns, sqlgraph.NewFieldSpec(usagedetail.FieldID, field.TypeUint64))
+	if ps := udu.mutation.predicates; len(ps) > 0 {
+		_spec.Predicate = func(selector *sql.Selector) {
+			for i := range ps {
+				ps[i](selector)
+			}
+		}
+	}
+	if value, ok := udu.mutation.UpdatedAt(); ok {
+		_spec.SetField(usagedetail.FieldUpdatedAt, field.TypeTime, value)
+	}
+	if value, ok := udu.mutation.Status(); ok {
+		_spec.SetField(usagedetail.FieldStatus, field.TypeUint8, value)
+	}
+	if value, ok := udu.mutation.AddedStatus(); ok {
+		_spec.AddField(usagedetail.FieldStatus, field.TypeUint8, value)
+	}
+	if udu.mutation.StatusCleared() {
+		_spec.ClearField(usagedetail.FieldStatus, field.TypeUint8)
+	}
+	if value, ok := udu.mutation.GetType(); ok {
+		_spec.SetField(usagedetail.FieldType, field.TypeInt, value)
+	}
+	if value, ok := udu.mutation.AddedType(); ok {
+		_spec.AddField(usagedetail.FieldType, field.TypeInt, value)
+	}
+	if udu.mutation.TypeCleared() {
+		_spec.ClearField(usagedetail.FieldType, field.TypeInt)
+	}
+	if value, ok := udu.mutation.BotID(); ok {
+		_spec.SetField(usagedetail.FieldBotID, field.TypeString, value)
+	}
+	if value, ok := udu.mutation.ReceiverID(); ok {
+		_spec.SetField(usagedetail.FieldReceiverID, field.TypeString, value)
+	}
+	if value, ok := udu.mutation.App(); ok {
+		_spec.SetField(usagedetail.FieldApp, field.TypeInt, value)
+	}
+	if value, ok := udu.mutation.AddedApp(); ok {
+		_spec.AddField(usagedetail.FieldApp, field.TypeInt, value)
+	}
+	if udu.mutation.AppCleared() {
+		_spec.ClearField(usagedetail.FieldApp, field.TypeInt)
+	}
+	if value, ok := udu.mutation.SessionID(); ok {
+		_spec.SetField(usagedetail.FieldSessionID, field.TypeUint64, value)
+	}
+	if value, ok := udu.mutation.AddedSessionID(); ok {
+		_spec.AddField(usagedetail.FieldSessionID, field.TypeUint64, value)
+	}
+	if udu.mutation.SessionIDCleared() {
+		_spec.ClearField(usagedetail.FieldSessionID, field.TypeUint64)
+	}
+	if value, ok := udu.mutation.Request(); ok {
+		_spec.SetField(usagedetail.FieldRequest, field.TypeString, value)
+	}
+	if value, ok := udu.mutation.Response(); ok {
+		_spec.SetField(usagedetail.FieldResponse, field.TypeString, value)
+	}
+	if value, ok := udu.mutation.TotalTokens(); ok {
+		_spec.SetField(usagedetail.FieldTotalTokens, field.TypeUint64, value)
+	}
+	if value, ok := udu.mutation.AddedTotalTokens(); ok {
+		_spec.AddField(usagedetail.FieldTotalTokens, field.TypeUint64, value)
+	}
+	if udu.mutation.TotalTokensCleared() {
+		_spec.ClearField(usagedetail.FieldTotalTokens, field.TypeUint64)
+	}
+	if value, ok := udu.mutation.PromptTokens(); ok {
+		_spec.SetField(usagedetail.FieldPromptTokens, field.TypeUint64, value)
+	}
+	if value, ok := udu.mutation.AddedPromptTokens(); ok {
+		_spec.AddField(usagedetail.FieldPromptTokens, field.TypeUint64, value)
+	}
+	if udu.mutation.PromptTokensCleared() {
+		_spec.ClearField(usagedetail.FieldPromptTokens, field.TypeUint64)
+	}
+	if value, ok := udu.mutation.CompletionTokens(); ok {
+		_spec.SetField(usagedetail.FieldCompletionTokens, field.TypeUint64, value)
+	}
+	if value, ok := udu.mutation.AddedCompletionTokens(); ok {
+		_spec.AddField(usagedetail.FieldCompletionTokens, field.TypeUint64, value)
+	}
+	if udu.mutation.CompletionTokensCleared() {
+		_spec.ClearField(usagedetail.FieldCompletionTokens, field.TypeUint64)
+	}
+	if value, ok := udu.mutation.OrganizationID(); ok {
+		_spec.SetField(usagedetail.FieldOrganizationID, field.TypeUint64, value)
+	}
+	if value, ok := udu.mutation.AddedOrganizationID(); ok {
+		_spec.AddField(usagedetail.FieldOrganizationID, field.TypeUint64, value)
+	}
+	if udu.mutation.OrganizationIDCleared() {
+		_spec.ClearField(usagedetail.FieldOrganizationID, field.TypeUint64)
+	}
+	if n, err = sqlgraph.UpdateNodes(ctx, udu.driver, _spec); err != nil {
+		if _, ok := err.(*sqlgraph.NotFoundError); ok {
+			err = &NotFoundError{usagedetail.Label}
+		} else if sqlgraph.IsConstraintError(err) {
+			err = &ConstraintError{msg: err.Error(), wrap: err}
+		}
+		return 0, err
+	}
+	udu.mutation.done = true
+	return n, nil
+}
+
+// UsageDetailUpdateOne is the builder for updating a single UsageDetail entity.
+type UsageDetailUpdateOne struct {
+	config
+	fields   []string
+	hooks    []Hook
+	mutation *UsageDetailMutation
+}
+
+// SetUpdatedAt sets the "updated_at" field.
+func (uduo *UsageDetailUpdateOne) SetUpdatedAt(t time.Time) *UsageDetailUpdateOne {
+	uduo.mutation.SetUpdatedAt(t)
+	return uduo
+}
+
+// SetStatus sets the "status" field.
+func (uduo *UsageDetailUpdateOne) SetStatus(u uint8) *UsageDetailUpdateOne {
+	uduo.mutation.ResetStatus()
+	uduo.mutation.SetStatus(u)
+	return uduo
+}
+
+// SetNillableStatus sets the "status" field if the given value is not nil.
+func (uduo *UsageDetailUpdateOne) SetNillableStatus(u *uint8) *UsageDetailUpdateOne {
+	if u != nil {
+		uduo.SetStatus(*u)
+	}
+	return uduo
+}
+
+// AddStatus adds u to the "status" field.
+func (uduo *UsageDetailUpdateOne) AddStatus(u int8) *UsageDetailUpdateOne {
+	uduo.mutation.AddStatus(u)
+	return uduo
+}
+
+// ClearStatus clears the value of the "status" field.
+func (uduo *UsageDetailUpdateOne) ClearStatus() *UsageDetailUpdateOne {
+	uduo.mutation.ClearStatus()
+	return uduo
+}
+
+// SetType sets the "type" field.
+func (uduo *UsageDetailUpdateOne) SetType(i int) *UsageDetailUpdateOne {
+	uduo.mutation.ResetType()
+	uduo.mutation.SetType(i)
+	return uduo
+}
+
+// SetNillableType sets the "type" field if the given value is not nil.
+func (uduo *UsageDetailUpdateOne) SetNillableType(i *int) *UsageDetailUpdateOne {
+	if i != nil {
+		uduo.SetType(*i)
+	}
+	return uduo
+}
+
+// AddType adds i to the "type" field.
+func (uduo *UsageDetailUpdateOne) AddType(i int) *UsageDetailUpdateOne {
+	uduo.mutation.AddType(i)
+	return uduo
+}
+
+// ClearType clears the value of the "type" field.
+func (uduo *UsageDetailUpdateOne) ClearType() *UsageDetailUpdateOne {
+	uduo.mutation.ClearType()
+	return uduo
+}
+
+// SetBotID sets the "bot_id" field.
+func (uduo *UsageDetailUpdateOne) SetBotID(s string) *UsageDetailUpdateOne {
+	uduo.mutation.SetBotID(s)
+	return uduo
+}
+
+// SetNillableBotID sets the "bot_id" field if the given value is not nil.
+func (uduo *UsageDetailUpdateOne) SetNillableBotID(s *string) *UsageDetailUpdateOne {
+	if s != nil {
+		uduo.SetBotID(*s)
+	}
+	return uduo
+}
+
+// SetReceiverID sets the "receiver_id" field.
+func (uduo *UsageDetailUpdateOne) SetReceiverID(s string) *UsageDetailUpdateOne {
+	uduo.mutation.SetReceiverID(s)
+	return uduo
+}
+
+// SetNillableReceiverID sets the "receiver_id" field if the given value is not nil.
+func (uduo *UsageDetailUpdateOne) SetNillableReceiverID(s *string) *UsageDetailUpdateOne {
+	if s != nil {
+		uduo.SetReceiverID(*s)
+	}
+	return uduo
+}
+
+// SetApp sets the "app" field.
+func (uduo *UsageDetailUpdateOne) SetApp(i int) *UsageDetailUpdateOne {
+	uduo.mutation.ResetApp()
+	uduo.mutation.SetApp(i)
+	return uduo
+}
+
+// SetNillableApp sets the "app" field if the given value is not nil.
+func (uduo *UsageDetailUpdateOne) SetNillableApp(i *int) *UsageDetailUpdateOne {
+	if i != nil {
+		uduo.SetApp(*i)
+	}
+	return uduo
+}
+
+// AddApp adds i to the "app" field.
+func (uduo *UsageDetailUpdateOne) AddApp(i int) *UsageDetailUpdateOne {
+	uduo.mutation.AddApp(i)
+	return uduo
+}
+
+// ClearApp clears the value of the "app" field.
+func (uduo *UsageDetailUpdateOne) ClearApp() *UsageDetailUpdateOne {
+	uduo.mutation.ClearApp()
+	return uduo
+}
+
+// SetSessionID sets the "session_id" field.
+func (uduo *UsageDetailUpdateOne) SetSessionID(u uint64) *UsageDetailUpdateOne {
+	uduo.mutation.ResetSessionID()
+	uduo.mutation.SetSessionID(u)
+	return uduo
+}
+
+// SetNillableSessionID sets the "session_id" field if the given value is not nil.
+func (uduo *UsageDetailUpdateOne) SetNillableSessionID(u *uint64) *UsageDetailUpdateOne {
+	if u != nil {
+		uduo.SetSessionID(*u)
+	}
+	return uduo
+}
+
+// AddSessionID adds u to the "session_id" field.
+func (uduo *UsageDetailUpdateOne) AddSessionID(u int64) *UsageDetailUpdateOne {
+	uduo.mutation.AddSessionID(u)
+	return uduo
+}
+
+// ClearSessionID clears the value of the "session_id" field.
+func (uduo *UsageDetailUpdateOne) ClearSessionID() *UsageDetailUpdateOne {
+	uduo.mutation.ClearSessionID()
+	return uduo
+}
+
+// SetRequest sets the "request" field.
+func (uduo *UsageDetailUpdateOne) SetRequest(s string) *UsageDetailUpdateOne {
+	uduo.mutation.SetRequest(s)
+	return uduo
+}
+
+// SetNillableRequest sets the "request" field if the given value is not nil.
+func (uduo *UsageDetailUpdateOne) SetNillableRequest(s *string) *UsageDetailUpdateOne {
+	if s != nil {
+		uduo.SetRequest(*s)
+	}
+	return uduo
+}
+
+// SetResponse sets the "response" field.
+func (uduo *UsageDetailUpdateOne) SetResponse(s string) *UsageDetailUpdateOne {
+	uduo.mutation.SetResponse(s)
+	return uduo
+}
+
+// SetNillableResponse sets the "response" field if the given value is not nil.
+func (uduo *UsageDetailUpdateOne) SetNillableResponse(s *string) *UsageDetailUpdateOne {
+	if s != nil {
+		uduo.SetResponse(*s)
+	}
+	return uduo
+}
+
+// SetTotalTokens sets the "total_tokens" field.
+func (uduo *UsageDetailUpdateOne) SetTotalTokens(u uint64) *UsageDetailUpdateOne {
+	uduo.mutation.ResetTotalTokens()
+	uduo.mutation.SetTotalTokens(u)
+	return uduo
+}
+
+// SetNillableTotalTokens sets the "total_tokens" field if the given value is not nil.
+func (uduo *UsageDetailUpdateOne) SetNillableTotalTokens(u *uint64) *UsageDetailUpdateOne {
+	if u != nil {
+		uduo.SetTotalTokens(*u)
+	}
+	return uduo
+}
+
+// AddTotalTokens adds u to the "total_tokens" field.
+func (uduo *UsageDetailUpdateOne) AddTotalTokens(u int64) *UsageDetailUpdateOne {
+	uduo.mutation.AddTotalTokens(u)
+	return uduo
+}
+
+// ClearTotalTokens clears the value of the "total_tokens" field.
+func (uduo *UsageDetailUpdateOne) ClearTotalTokens() *UsageDetailUpdateOne {
+	uduo.mutation.ClearTotalTokens()
+	return uduo
+}
+
+// SetPromptTokens sets the "prompt_tokens" field.
+func (uduo *UsageDetailUpdateOne) SetPromptTokens(u uint64) *UsageDetailUpdateOne {
+	uduo.mutation.ResetPromptTokens()
+	uduo.mutation.SetPromptTokens(u)
+	return uduo
+}
+
+// SetNillablePromptTokens sets the "prompt_tokens" field if the given value is not nil.
+func (uduo *UsageDetailUpdateOne) SetNillablePromptTokens(u *uint64) *UsageDetailUpdateOne {
+	if u != nil {
+		uduo.SetPromptTokens(*u)
+	}
+	return uduo
+}
+
+// AddPromptTokens adds u to the "prompt_tokens" field.
+func (uduo *UsageDetailUpdateOne) AddPromptTokens(u int64) *UsageDetailUpdateOne {
+	uduo.mutation.AddPromptTokens(u)
+	return uduo
+}
+
+// ClearPromptTokens clears the value of the "prompt_tokens" field.
+func (uduo *UsageDetailUpdateOne) ClearPromptTokens() *UsageDetailUpdateOne {
+	uduo.mutation.ClearPromptTokens()
+	return uduo
+}
+
+// SetCompletionTokens sets the "completion_tokens" field.
+func (uduo *UsageDetailUpdateOne) SetCompletionTokens(u uint64) *UsageDetailUpdateOne {
+	uduo.mutation.ResetCompletionTokens()
+	uduo.mutation.SetCompletionTokens(u)
+	return uduo
+}
+
+// SetNillableCompletionTokens sets the "completion_tokens" field if the given value is not nil.
+func (uduo *UsageDetailUpdateOne) SetNillableCompletionTokens(u *uint64) *UsageDetailUpdateOne {
+	if u != nil {
+		uduo.SetCompletionTokens(*u)
+	}
+	return uduo
+}
+
+// AddCompletionTokens adds u to the "completion_tokens" field.
+func (uduo *UsageDetailUpdateOne) AddCompletionTokens(u int64) *UsageDetailUpdateOne {
+	uduo.mutation.AddCompletionTokens(u)
+	return uduo
+}
+
+// ClearCompletionTokens clears the value of the "completion_tokens" field.
+func (uduo *UsageDetailUpdateOne) ClearCompletionTokens() *UsageDetailUpdateOne {
+	uduo.mutation.ClearCompletionTokens()
+	return uduo
+}
+
+// SetOrganizationID sets the "organization_id" field.
+func (uduo *UsageDetailUpdateOne) SetOrganizationID(u uint64) *UsageDetailUpdateOne {
+	uduo.mutation.ResetOrganizationID()
+	uduo.mutation.SetOrganizationID(u)
+	return uduo
+}
+
+// SetNillableOrganizationID sets the "organization_id" field if the given value is not nil.
+func (uduo *UsageDetailUpdateOne) SetNillableOrganizationID(u *uint64) *UsageDetailUpdateOne {
+	if u != nil {
+		uduo.SetOrganizationID(*u)
+	}
+	return uduo
+}
+
+// AddOrganizationID adds u to the "organization_id" field.
+func (uduo *UsageDetailUpdateOne) AddOrganizationID(u int64) *UsageDetailUpdateOne {
+	uduo.mutation.AddOrganizationID(u)
+	return uduo
+}
+
+// ClearOrganizationID clears the value of the "organization_id" field.
+func (uduo *UsageDetailUpdateOne) ClearOrganizationID() *UsageDetailUpdateOne {
+	uduo.mutation.ClearOrganizationID()
+	return uduo
+}
+
+// Mutation returns the UsageDetailMutation object of the builder.
+func (uduo *UsageDetailUpdateOne) Mutation() *UsageDetailMutation {
+	return uduo.mutation
+}
+
+// Where appends a list predicates to the UsageDetailUpdate builder.
+func (uduo *UsageDetailUpdateOne) Where(ps ...predicate.UsageDetail) *UsageDetailUpdateOne {
+	uduo.mutation.Where(ps...)
+	return uduo
+}
+
+// Select allows selecting one or more fields (columns) of the returned entity.
+// The default is selecting all fields defined in the entity schema.
+func (uduo *UsageDetailUpdateOne) Select(field string, fields ...string) *UsageDetailUpdateOne {
+	uduo.fields = append([]string{field}, fields...)
+	return uduo
+}
+
+// Save executes the query and returns the updated UsageDetail entity.
+func (uduo *UsageDetailUpdateOne) Save(ctx context.Context) (*UsageDetail, error) {
+	uduo.defaults()
+	return withHooks(ctx, uduo.sqlSave, uduo.mutation, uduo.hooks)
+}
+
+// SaveX is like Save, but panics if an error occurs.
+func (uduo *UsageDetailUpdateOne) SaveX(ctx context.Context) *UsageDetail {
+	node, err := uduo.Save(ctx)
+	if err != nil {
+		panic(err)
+	}
+	return node
+}
+
+// Exec executes the query on the entity.
+func (uduo *UsageDetailUpdateOne) Exec(ctx context.Context) error {
+	_, err := uduo.Save(ctx)
+	return err
+}
+
+// ExecX is like Exec, but panics if an error occurs.
+func (uduo *UsageDetailUpdateOne) ExecX(ctx context.Context) {
+	if err := uduo.Exec(ctx); err != nil {
+		panic(err)
+	}
+}
+
+// defaults sets the default values of the builder before save.
+func (uduo *UsageDetailUpdateOne) defaults() {
+	if _, ok := uduo.mutation.UpdatedAt(); !ok {
+		v := usagedetail.UpdateDefaultUpdatedAt()
+		uduo.mutation.SetUpdatedAt(v)
+	}
+}
+
+func (uduo *UsageDetailUpdateOne) sqlSave(ctx context.Context) (_node *UsageDetail, err error) {
+	_spec := sqlgraph.NewUpdateSpec(usagedetail.Table, usagedetail.Columns, sqlgraph.NewFieldSpec(usagedetail.FieldID, field.TypeUint64))
+	id, ok := uduo.mutation.ID()
+	if !ok {
+		return nil, &ValidationError{Name: "id", err: errors.New(`ent: missing "UsageDetail.id" for update`)}
+	}
+	_spec.Node.ID.Value = id
+	if fields := uduo.fields; len(fields) > 0 {
+		_spec.Node.Columns = make([]string, 0, len(fields))
+		_spec.Node.Columns = append(_spec.Node.Columns, usagedetail.FieldID)
+		for _, f := range fields {
+			if !usagedetail.ValidColumn(f) {
+				return nil, &ValidationError{Name: f, err: fmt.Errorf("ent: invalid field %q for query", f)}
+			}
+			if f != usagedetail.FieldID {
+				_spec.Node.Columns = append(_spec.Node.Columns, f)
+			}
+		}
+	}
+	if ps := uduo.mutation.predicates; len(ps) > 0 {
+		_spec.Predicate = func(selector *sql.Selector) {
+			for i := range ps {
+				ps[i](selector)
+			}
+		}
+	}
+	if value, ok := uduo.mutation.UpdatedAt(); ok {
+		_spec.SetField(usagedetail.FieldUpdatedAt, field.TypeTime, value)
+	}
+	if value, ok := uduo.mutation.Status(); ok {
+		_spec.SetField(usagedetail.FieldStatus, field.TypeUint8, value)
+	}
+	if value, ok := uduo.mutation.AddedStatus(); ok {
+		_spec.AddField(usagedetail.FieldStatus, field.TypeUint8, value)
+	}
+	if uduo.mutation.StatusCleared() {
+		_spec.ClearField(usagedetail.FieldStatus, field.TypeUint8)
+	}
+	if value, ok := uduo.mutation.GetType(); ok {
+		_spec.SetField(usagedetail.FieldType, field.TypeInt, value)
+	}
+	if value, ok := uduo.mutation.AddedType(); ok {
+		_spec.AddField(usagedetail.FieldType, field.TypeInt, value)
+	}
+	if uduo.mutation.TypeCleared() {
+		_spec.ClearField(usagedetail.FieldType, field.TypeInt)
+	}
+	if value, ok := uduo.mutation.BotID(); ok {
+		_spec.SetField(usagedetail.FieldBotID, field.TypeString, value)
+	}
+	if value, ok := uduo.mutation.ReceiverID(); ok {
+		_spec.SetField(usagedetail.FieldReceiverID, field.TypeString, value)
+	}
+	if value, ok := uduo.mutation.App(); ok {
+		_spec.SetField(usagedetail.FieldApp, field.TypeInt, value)
+	}
+	if value, ok := uduo.mutation.AddedApp(); ok {
+		_spec.AddField(usagedetail.FieldApp, field.TypeInt, value)
+	}
+	if uduo.mutation.AppCleared() {
+		_spec.ClearField(usagedetail.FieldApp, field.TypeInt)
+	}
+	if value, ok := uduo.mutation.SessionID(); ok {
+		_spec.SetField(usagedetail.FieldSessionID, field.TypeUint64, value)
+	}
+	if value, ok := uduo.mutation.AddedSessionID(); ok {
+		_spec.AddField(usagedetail.FieldSessionID, field.TypeUint64, value)
+	}
+	if uduo.mutation.SessionIDCleared() {
+		_spec.ClearField(usagedetail.FieldSessionID, field.TypeUint64)
+	}
+	if value, ok := uduo.mutation.Request(); ok {
+		_spec.SetField(usagedetail.FieldRequest, field.TypeString, value)
+	}
+	if value, ok := uduo.mutation.Response(); ok {
+		_spec.SetField(usagedetail.FieldResponse, field.TypeString, value)
+	}
+	if value, ok := uduo.mutation.TotalTokens(); ok {
+		_spec.SetField(usagedetail.FieldTotalTokens, field.TypeUint64, value)
+	}
+	if value, ok := uduo.mutation.AddedTotalTokens(); ok {
+		_spec.AddField(usagedetail.FieldTotalTokens, field.TypeUint64, value)
+	}
+	if uduo.mutation.TotalTokensCleared() {
+		_spec.ClearField(usagedetail.FieldTotalTokens, field.TypeUint64)
+	}
+	if value, ok := uduo.mutation.PromptTokens(); ok {
+		_spec.SetField(usagedetail.FieldPromptTokens, field.TypeUint64, value)
+	}
+	if value, ok := uduo.mutation.AddedPromptTokens(); ok {
+		_spec.AddField(usagedetail.FieldPromptTokens, field.TypeUint64, value)
+	}
+	if uduo.mutation.PromptTokensCleared() {
+		_spec.ClearField(usagedetail.FieldPromptTokens, field.TypeUint64)
+	}
+	if value, ok := uduo.mutation.CompletionTokens(); ok {
+		_spec.SetField(usagedetail.FieldCompletionTokens, field.TypeUint64, value)
+	}
+	if value, ok := uduo.mutation.AddedCompletionTokens(); ok {
+		_spec.AddField(usagedetail.FieldCompletionTokens, field.TypeUint64, value)
+	}
+	if uduo.mutation.CompletionTokensCleared() {
+		_spec.ClearField(usagedetail.FieldCompletionTokens, field.TypeUint64)
+	}
+	if value, ok := uduo.mutation.OrganizationID(); ok {
+		_spec.SetField(usagedetail.FieldOrganizationID, field.TypeUint64, value)
+	}
+	if value, ok := uduo.mutation.AddedOrganizationID(); ok {
+		_spec.AddField(usagedetail.FieldOrganizationID, field.TypeUint64, value)
+	}
+	if uduo.mutation.OrganizationIDCleared() {
+		_spec.ClearField(usagedetail.FieldOrganizationID, field.TypeUint64)
+	}
+	_node = &UsageDetail{config: uduo.config}
+	_spec.Assign = _node.assignValues
+	_spec.ScanValues = _node.scanValues
+	if err = sqlgraph.UpdateNode(ctx, uduo.driver, _spec); err != nil {
+		if _, ok := err.(*sqlgraph.NotFoundError); ok {
+			err = &NotFoundError{usagedetail.Label}
+		} else if sqlgraph.IsConstraintError(err) {
+			err = &ConstraintError{msg: err.Error(), wrap: err}
+		}
+		return nil, err
+	}
+	uduo.mutation.done = true
+	return _node, nil
+}

+ 194 - 0
ent/usagetotal.go

@@ -0,0 +1,194 @@
+// Code generated by ent, DO NOT EDIT.
+
+package ent
+
+import (
+	"fmt"
+	"strings"
+	"time"
+	"wechat-api/ent/usagetotal"
+
+	"entgo.io/ent"
+	"entgo.io/ent/dialect/sql"
+)
+
+// UsageTotal is the model entity for the UsageTotal schema.
+type UsageTotal struct {
+	config `json:"-"`
+	// ID of the ent.
+	ID uint64 `json:"id,omitempty"`
+	// Create Time | 创建日期
+	CreatedAt time.Time `json:"created_at,omitempty"`
+	// Update Time | 修改日期
+	UpdatedAt time.Time `json:"updated_at,omitempty"`
+	// Status 1: normal 2: ban | 状态 1 正常 2 禁用
+	Status uint8 `json:"status,omitempty"`
+	// 1 微信 2 名片
+	Type int `json:"type,omitempty"`
+	// 微信或名片id
+	BotID string `json:"bot_id,omitempty"`
+	// 使用token总数
+	TotalTokens uint64 `json:"total_tokens,omitempty"`
+	// 重制后的起始usage_detail 索引
+	StartIndex uint64 `json:"start_index,omitempty"`
+	// usage_detail 索引
+	EndIndex uint64 `json:"end_index,omitempty"`
+	// 机构 ID
+	OrganizationID uint64 `json:"organization_id,omitempty"`
+	selectValues   sql.SelectValues
+}
+
+// scanValues returns the types for scanning values from sql.Rows.
+func (*UsageTotal) scanValues(columns []string) ([]any, error) {
+	values := make([]any, len(columns))
+	for i := range columns {
+		switch columns[i] {
+		case usagetotal.FieldID, usagetotal.FieldStatus, usagetotal.FieldType, usagetotal.FieldTotalTokens, usagetotal.FieldStartIndex, usagetotal.FieldEndIndex, usagetotal.FieldOrganizationID:
+			values[i] = new(sql.NullInt64)
+		case usagetotal.FieldBotID:
+			values[i] = new(sql.NullString)
+		case usagetotal.FieldCreatedAt, usagetotal.FieldUpdatedAt:
+			values[i] = new(sql.NullTime)
+		default:
+			values[i] = new(sql.UnknownType)
+		}
+	}
+	return values, nil
+}
+
+// assignValues assigns the values that were returned from sql.Rows (after scanning)
+// to the UsageTotal fields.
+func (ut *UsageTotal) 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 usagetotal.FieldID:
+			value, ok := values[i].(*sql.NullInt64)
+			if !ok {
+				return fmt.Errorf("unexpected type %T for field id", value)
+			}
+			ut.ID = uint64(value.Int64)
+		case usagetotal.FieldCreatedAt:
+			if value, ok := values[i].(*sql.NullTime); !ok {
+				return fmt.Errorf("unexpected type %T for field created_at", values[i])
+			} else if value.Valid {
+				ut.CreatedAt = value.Time
+			}
+		case usagetotal.FieldUpdatedAt:
+			if value, ok := values[i].(*sql.NullTime); !ok {
+				return fmt.Errorf("unexpected type %T for field updated_at", values[i])
+			} else if value.Valid {
+				ut.UpdatedAt = value.Time
+			}
+		case usagetotal.FieldStatus:
+			if value, ok := values[i].(*sql.NullInt64); !ok {
+				return fmt.Errorf("unexpected type %T for field status", values[i])
+			} else if value.Valid {
+				ut.Status = uint8(value.Int64)
+			}
+		case usagetotal.FieldType:
+			if value, ok := values[i].(*sql.NullInt64); !ok {
+				return fmt.Errorf("unexpected type %T for field type", values[i])
+			} else if value.Valid {
+				ut.Type = int(value.Int64)
+			}
+		case usagetotal.FieldBotID:
+			if value, ok := values[i].(*sql.NullString); !ok {
+				return fmt.Errorf("unexpected type %T for field bot_id", values[i])
+			} else if value.Valid {
+				ut.BotID = value.String
+			}
+		case usagetotal.FieldTotalTokens:
+			if value, ok := values[i].(*sql.NullInt64); !ok {
+				return fmt.Errorf("unexpected type %T for field total_tokens", values[i])
+			} else if value.Valid {
+				ut.TotalTokens = uint64(value.Int64)
+			}
+		case usagetotal.FieldStartIndex:
+			if value, ok := values[i].(*sql.NullInt64); !ok {
+				return fmt.Errorf("unexpected type %T for field start_index", values[i])
+			} else if value.Valid {
+				ut.StartIndex = uint64(value.Int64)
+			}
+		case usagetotal.FieldEndIndex:
+			if value, ok := values[i].(*sql.NullInt64); !ok {
+				return fmt.Errorf("unexpected type %T for field end_index", values[i])
+			} else if value.Valid {
+				ut.EndIndex = uint64(value.Int64)
+			}
+		case usagetotal.FieldOrganizationID:
+			if value, ok := values[i].(*sql.NullInt64); !ok {
+				return fmt.Errorf("unexpected type %T for field organization_id", values[i])
+			} else if value.Valid {
+				ut.OrganizationID = uint64(value.Int64)
+			}
+		default:
+			ut.selectValues.Set(columns[i], values[i])
+		}
+	}
+	return nil
+}
+
+// Value returns the ent.Value that was dynamically selected and assigned to the UsageTotal.
+// This includes values selected through modifiers, order, etc.
+func (ut *UsageTotal) Value(name string) (ent.Value, error) {
+	return ut.selectValues.Get(name)
+}
+
+// Update returns a builder for updating this UsageTotal.
+// Note that you need to call UsageTotal.Unwrap() before calling this method if this UsageTotal
+// was returned from a transaction, and the transaction was committed or rolled back.
+func (ut *UsageTotal) Update() *UsageTotalUpdateOne {
+	return NewUsageTotalClient(ut.config).UpdateOne(ut)
+}
+
+// Unwrap unwraps the UsageTotal 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 (ut *UsageTotal) Unwrap() *UsageTotal {
+	_tx, ok := ut.config.driver.(*txDriver)
+	if !ok {
+		panic("ent: UsageTotal is not a transactional entity")
+	}
+	ut.config.driver = _tx.drv
+	return ut
+}
+
+// String implements the fmt.Stringer.
+func (ut *UsageTotal) String() string {
+	var builder strings.Builder
+	builder.WriteString("UsageTotal(")
+	builder.WriteString(fmt.Sprintf("id=%v, ", ut.ID))
+	builder.WriteString("created_at=")
+	builder.WriteString(ut.CreatedAt.Format(time.ANSIC))
+	builder.WriteString(", ")
+	builder.WriteString("updated_at=")
+	builder.WriteString(ut.UpdatedAt.Format(time.ANSIC))
+	builder.WriteString(", ")
+	builder.WriteString("status=")
+	builder.WriteString(fmt.Sprintf("%v", ut.Status))
+	builder.WriteString(", ")
+	builder.WriteString("type=")
+	builder.WriteString(fmt.Sprintf("%v", ut.Type))
+	builder.WriteString(", ")
+	builder.WriteString("bot_id=")
+	builder.WriteString(ut.BotID)
+	builder.WriteString(", ")
+	builder.WriteString("total_tokens=")
+	builder.WriteString(fmt.Sprintf("%v", ut.TotalTokens))
+	builder.WriteString(", ")
+	builder.WriteString("start_index=")
+	builder.WriteString(fmt.Sprintf("%v", ut.StartIndex))
+	builder.WriteString(", ")
+	builder.WriteString("end_index=")
+	builder.WriteString(fmt.Sprintf("%v", ut.EndIndex))
+	builder.WriteString(", ")
+	builder.WriteString("organization_id=")
+	builder.WriteString(fmt.Sprintf("%v", ut.OrganizationID))
+	builder.WriteByte(')')
+	return builder.String()
+}
+
+// UsageTotals is a parsable slice of UsageTotal.
+type UsageTotals []*UsageTotal

+ 136 - 0
ent/usagetotal/usagetotal.go

@@ -0,0 +1,136 @@
+// Code generated by ent, DO NOT EDIT.
+
+package usagetotal
+
+import (
+	"time"
+
+	"entgo.io/ent/dialect/sql"
+)
+
+const (
+	// Label holds the string label denoting the usagetotal type in the database.
+	Label = "usage_total"
+	// FieldID holds the string denoting the id field in the database.
+	FieldID = "id"
+	// FieldCreatedAt holds the string denoting the created_at field in the database.
+	FieldCreatedAt = "created_at"
+	// FieldUpdatedAt holds the string denoting the updated_at field in the database.
+	FieldUpdatedAt = "updated_at"
+	// FieldStatus holds the string denoting the status field in the database.
+	FieldStatus = "status"
+	// FieldType holds the string denoting the type field in the database.
+	FieldType = "type"
+	// FieldBotID holds the string denoting the bot_id field in the database.
+	FieldBotID = "bot_id"
+	// FieldTotalTokens holds the string denoting the total_tokens field in the database.
+	FieldTotalTokens = "total_tokens"
+	// FieldStartIndex holds the string denoting the start_index field in the database.
+	FieldStartIndex = "start_index"
+	// FieldEndIndex holds the string denoting the end_index field in the database.
+	FieldEndIndex = "end_index"
+	// FieldOrganizationID holds the string denoting the organization_id field in the database.
+	FieldOrganizationID = "organization_id"
+	// Table holds the table name of the usagetotal in the database.
+	Table = "usage_total"
+)
+
+// Columns holds all SQL columns for usagetotal fields.
+var Columns = []string{
+	FieldID,
+	FieldCreatedAt,
+	FieldUpdatedAt,
+	FieldStatus,
+	FieldType,
+	FieldBotID,
+	FieldTotalTokens,
+	FieldStartIndex,
+	FieldEndIndex,
+	FieldOrganizationID,
+}
+
+// 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 (
+	// DefaultCreatedAt holds the default value on creation for the "created_at" field.
+	DefaultCreatedAt func() time.Time
+	// DefaultUpdatedAt holds the default value on creation for the "updated_at" field.
+	DefaultUpdatedAt func() time.Time
+	// UpdateDefaultUpdatedAt holds the default value on update for the "updated_at" field.
+	UpdateDefaultUpdatedAt func() time.Time
+	// DefaultStatus holds the default value on creation for the "status" field.
+	DefaultStatus uint8
+	// DefaultType holds the default value on creation for the "type" field.
+	DefaultType int
+	// DefaultBotID holds the default value on creation for the "bot_id" field.
+	DefaultBotID string
+	// DefaultTotalTokens holds the default value on creation for the "total_tokens" field.
+	DefaultTotalTokens uint64
+	// DefaultStartIndex holds the default value on creation for the "start_index" field.
+	DefaultStartIndex uint64
+	// DefaultEndIndex holds the default value on creation for the "end_index" field.
+	DefaultEndIndex uint64
+	// DefaultOrganizationID holds the default value on creation for the "organization_id" field.
+	DefaultOrganizationID uint64
+)
+
+// OrderOption defines the ordering options for the UsageTotal 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()
+}
+
+// ByCreatedAt orders the results by the created_at field.
+func ByCreatedAt(opts ...sql.OrderTermOption) OrderOption {
+	return sql.OrderByField(FieldCreatedAt, opts...).ToFunc()
+}
+
+// ByUpdatedAt orders the results by the updated_at field.
+func ByUpdatedAt(opts ...sql.OrderTermOption) OrderOption {
+	return sql.OrderByField(FieldUpdatedAt, opts...).ToFunc()
+}
+
+// ByStatus orders the results by the status field.
+func ByStatus(opts ...sql.OrderTermOption) OrderOption {
+	return sql.OrderByField(FieldStatus, opts...).ToFunc()
+}
+
+// ByType orders the results by the type field.
+func ByType(opts ...sql.OrderTermOption) OrderOption {
+	return sql.OrderByField(FieldType, opts...).ToFunc()
+}
+
+// ByBotID orders the results by the bot_id field.
+func ByBotID(opts ...sql.OrderTermOption) OrderOption {
+	return sql.OrderByField(FieldBotID, opts...).ToFunc()
+}
+
+// ByTotalTokens orders the results by the total_tokens field.
+func ByTotalTokens(opts ...sql.OrderTermOption) OrderOption {
+	return sql.OrderByField(FieldTotalTokens, opts...).ToFunc()
+}
+
+// ByStartIndex orders the results by the start_index field.
+func ByStartIndex(opts ...sql.OrderTermOption) OrderOption {
+	return sql.OrderByField(FieldStartIndex, opts...).ToFunc()
+}
+
+// ByEndIndex orders the results by the end_index field.
+func ByEndIndex(opts ...sql.OrderTermOption) OrderOption {
+	return sql.OrderByField(FieldEndIndex, opts...).ToFunc()
+}
+
+// ByOrganizationID orders the results by the organization_id field.
+func ByOrganizationID(opts ...sql.OrderTermOption) OrderOption {
+	return sql.OrderByField(FieldOrganizationID, opts...).ToFunc()
+}

+ 560 - 0
ent/usagetotal/where.go

@@ -0,0 +1,560 @@
+// Code generated by ent, DO NOT EDIT.
+
+package usagetotal
+
+import (
+	"time"
+	"wechat-api/ent/predicate"
+
+	"entgo.io/ent/dialect/sql"
+)
+
+// ID filters vertices based on their ID field.
+func ID(id uint64) predicate.UsageTotal {
+	return predicate.UsageTotal(sql.FieldEQ(FieldID, id))
+}
+
+// IDEQ applies the EQ predicate on the ID field.
+func IDEQ(id uint64) predicate.UsageTotal {
+	return predicate.UsageTotal(sql.FieldEQ(FieldID, id))
+}
+
+// IDNEQ applies the NEQ predicate on the ID field.
+func IDNEQ(id uint64) predicate.UsageTotal {
+	return predicate.UsageTotal(sql.FieldNEQ(FieldID, id))
+}
+
+// IDIn applies the In predicate on the ID field.
+func IDIn(ids ...uint64) predicate.UsageTotal {
+	return predicate.UsageTotal(sql.FieldIn(FieldID, ids...))
+}
+
+// IDNotIn applies the NotIn predicate on the ID field.
+func IDNotIn(ids ...uint64) predicate.UsageTotal {
+	return predicate.UsageTotal(sql.FieldNotIn(FieldID, ids...))
+}
+
+// IDGT applies the GT predicate on the ID field.
+func IDGT(id uint64) predicate.UsageTotal {
+	return predicate.UsageTotal(sql.FieldGT(FieldID, id))
+}
+
+// IDGTE applies the GTE predicate on the ID field.
+func IDGTE(id uint64) predicate.UsageTotal {
+	return predicate.UsageTotal(sql.FieldGTE(FieldID, id))
+}
+
+// IDLT applies the LT predicate on the ID field.
+func IDLT(id uint64) predicate.UsageTotal {
+	return predicate.UsageTotal(sql.FieldLT(FieldID, id))
+}
+
+// IDLTE applies the LTE predicate on the ID field.
+func IDLTE(id uint64) predicate.UsageTotal {
+	return predicate.UsageTotal(sql.FieldLTE(FieldID, id))
+}
+
+// CreatedAt applies equality check predicate on the "created_at" field. It's identical to CreatedAtEQ.
+func CreatedAt(v time.Time) predicate.UsageTotal {
+	return predicate.UsageTotal(sql.FieldEQ(FieldCreatedAt, v))
+}
+
+// UpdatedAt applies equality check predicate on the "updated_at" field. It's identical to UpdatedAtEQ.
+func UpdatedAt(v time.Time) predicate.UsageTotal {
+	return predicate.UsageTotal(sql.FieldEQ(FieldUpdatedAt, v))
+}
+
+// Status applies equality check predicate on the "status" field. It's identical to StatusEQ.
+func Status(v uint8) predicate.UsageTotal {
+	return predicate.UsageTotal(sql.FieldEQ(FieldStatus, v))
+}
+
+// Type applies equality check predicate on the "type" field. It's identical to TypeEQ.
+func Type(v int) predicate.UsageTotal {
+	return predicate.UsageTotal(sql.FieldEQ(FieldType, v))
+}
+
+// BotID applies equality check predicate on the "bot_id" field. It's identical to BotIDEQ.
+func BotID(v string) predicate.UsageTotal {
+	return predicate.UsageTotal(sql.FieldEQ(FieldBotID, v))
+}
+
+// TotalTokens applies equality check predicate on the "total_tokens" field. It's identical to TotalTokensEQ.
+func TotalTokens(v uint64) predicate.UsageTotal {
+	return predicate.UsageTotal(sql.FieldEQ(FieldTotalTokens, v))
+}
+
+// StartIndex applies equality check predicate on the "start_index" field. It's identical to StartIndexEQ.
+func StartIndex(v uint64) predicate.UsageTotal {
+	return predicate.UsageTotal(sql.FieldEQ(FieldStartIndex, v))
+}
+
+// EndIndex applies equality check predicate on the "end_index" field. It's identical to EndIndexEQ.
+func EndIndex(v uint64) predicate.UsageTotal {
+	return predicate.UsageTotal(sql.FieldEQ(FieldEndIndex, v))
+}
+
+// OrganizationID applies equality check predicate on the "organization_id" field. It's identical to OrganizationIDEQ.
+func OrganizationID(v uint64) predicate.UsageTotal {
+	return predicate.UsageTotal(sql.FieldEQ(FieldOrganizationID, v))
+}
+
+// CreatedAtEQ applies the EQ predicate on the "created_at" field.
+func CreatedAtEQ(v time.Time) predicate.UsageTotal {
+	return predicate.UsageTotal(sql.FieldEQ(FieldCreatedAt, v))
+}
+
+// CreatedAtNEQ applies the NEQ predicate on the "created_at" field.
+func CreatedAtNEQ(v time.Time) predicate.UsageTotal {
+	return predicate.UsageTotal(sql.FieldNEQ(FieldCreatedAt, v))
+}
+
+// CreatedAtIn applies the In predicate on the "created_at" field.
+func CreatedAtIn(vs ...time.Time) predicate.UsageTotal {
+	return predicate.UsageTotal(sql.FieldIn(FieldCreatedAt, vs...))
+}
+
+// CreatedAtNotIn applies the NotIn predicate on the "created_at" field.
+func CreatedAtNotIn(vs ...time.Time) predicate.UsageTotal {
+	return predicate.UsageTotal(sql.FieldNotIn(FieldCreatedAt, vs...))
+}
+
+// CreatedAtGT applies the GT predicate on the "created_at" field.
+func CreatedAtGT(v time.Time) predicate.UsageTotal {
+	return predicate.UsageTotal(sql.FieldGT(FieldCreatedAt, v))
+}
+
+// CreatedAtGTE applies the GTE predicate on the "created_at" field.
+func CreatedAtGTE(v time.Time) predicate.UsageTotal {
+	return predicate.UsageTotal(sql.FieldGTE(FieldCreatedAt, v))
+}
+
+// CreatedAtLT applies the LT predicate on the "created_at" field.
+func CreatedAtLT(v time.Time) predicate.UsageTotal {
+	return predicate.UsageTotal(sql.FieldLT(FieldCreatedAt, v))
+}
+
+// CreatedAtLTE applies the LTE predicate on the "created_at" field.
+func CreatedAtLTE(v time.Time) predicate.UsageTotal {
+	return predicate.UsageTotal(sql.FieldLTE(FieldCreatedAt, v))
+}
+
+// UpdatedAtEQ applies the EQ predicate on the "updated_at" field.
+func UpdatedAtEQ(v time.Time) predicate.UsageTotal {
+	return predicate.UsageTotal(sql.FieldEQ(FieldUpdatedAt, v))
+}
+
+// UpdatedAtNEQ applies the NEQ predicate on the "updated_at" field.
+func UpdatedAtNEQ(v time.Time) predicate.UsageTotal {
+	return predicate.UsageTotal(sql.FieldNEQ(FieldUpdatedAt, v))
+}
+
+// UpdatedAtIn applies the In predicate on the "updated_at" field.
+func UpdatedAtIn(vs ...time.Time) predicate.UsageTotal {
+	return predicate.UsageTotal(sql.FieldIn(FieldUpdatedAt, vs...))
+}
+
+// UpdatedAtNotIn applies the NotIn predicate on the "updated_at" field.
+func UpdatedAtNotIn(vs ...time.Time) predicate.UsageTotal {
+	return predicate.UsageTotal(sql.FieldNotIn(FieldUpdatedAt, vs...))
+}
+
+// UpdatedAtGT applies the GT predicate on the "updated_at" field.
+func UpdatedAtGT(v time.Time) predicate.UsageTotal {
+	return predicate.UsageTotal(sql.FieldGT(FieldUpdatedAt, v))
+}
+
+// UpdatedAtGTE applies the GTE predicate on the "updated_at" field.
+func UpdatedAtGTE(v time.Time) predicate.UsageTotal {
+	return predicate.UsageTotal(sql.FieldGTE(FieldUpdatedAt, v))
+}
+
+// UpdatedAtLT applies the LT predicate on the "updated_at" field.
+func UpdatedAtLT(v time.Time) predicate.UsageTotal {
+	return predicate.UsageTotal(sql.FieldLT(FieldUpdatedAt, v))
+}
+
+// UpdatedAtLTE applies the LTE predicate on the "updated_at" field.
+func UpdatedAtLTE(v time.Time) predicate.UsageTotal {
+	return predicate.UsageTotal(sql.FieldLTE(FieldUpdatedAt, v))
+}
+
+// StatusEQ applies the EQ predicate on the "status" field.
+func StatusEQ(v uint8) predicate.UsageTotal {
+	return predicate.UsageTotal(sql.FieldEQ(FieldStatus, v))
+}
+
+// StatusNEQ applies the NEQ predicate on the "status" field.
+func StatusNEQ(v uint8) predicate.UsageTotal {
+	return predicate.UsageTotal(sql.FieldNEQ(FieldStatus, v))
+}
+
+// StatusIn applies the In predicate on the "status" field.
+func StatusIn(vs ...uint8) predicate.UsageTotal {
+	return predicate.UsageTotal(sql.FieldIn(FieldStatus, vs...))
+}
+
+// StatusNotIn applies the NotIn predicate on the "status" field.
+func StatusNotIn(vs ...uint8) predicate.UsageTotal {
+	return predicate.UsageTotal(sql.FieldNotIn(FieldStatus, vs...))
+}
+
+// StatusGT applies the GT predicate on the "status" field.
+func StatusGT(v uint8) predicate.UsageTotal {
+	return predicate.UsageTotal(sql.FieldGT(FieldStatus, v))
+}
+
+// StatusGTE applies the GTE predicate on the "status" field.
+func StatusGTE(v uint8) predicate.UsageTotal {
+	return predicate.UsageTotal(sql.FieldGTE(FieldStatus, v))
+}
+
+// StatusLT applies the LT predicate on the "status" field.
+func StatusLT(v uint8) predicate.UsageTotal {
+	return predicate.UsageTotal(sql.FieldLT(FieldStatus, v))
+}
+
+// StatusLTE applies the LTE predicate on the "status" field.
+func StatusLTE(v uint8) predicate.UsageTotal {
+	return predicate.UsageTotal(sql.FieldLTE(FieldStatus, v))
+}
+
+// StatusIsNil applies the IsNil predicate on the "status" field.
+func StatusIsNil() predicate.UsageTotal {
+	return predicate.UsageTotal(sql.FieldIsNull(FieldStatus))
+}
+
+// StatusNotNil applies the NotNil predicate on the "status" field.
+func StatusNotNil() predicate.UsageTotal {
+	return predicate.UsageTotal(sql.FieldNotNull(FieldStatus))
+}
+
+// TypeEQ applies the EQ predicate on the "type" field.
+func TypeEQ(v int) predicate.UsageTotal {
+	return predicate.UsageTotal(sql.FieldEQ(FieldType, v))
+}
+
+// TypeNEQ applies the NEQ predicate on the "type" field.
+func TypeNEQ(v int) predicate.UsageTotal {
+	return predicate.UsageTotal(sql.FieldNEQ(FieldType, v))
+}
+
+// TypeIn applies the In predicate on the "type" field.
+func TypeIn(vs ...int) predicate.UsageTotal {
+	return predicate.UsageTotal(sql.FieldIn(FieldType, vs...))
+}
+
+// TypeNotIn applies the NotIn predicate on the "type" field.
+func TypeNotIn(vs ...int) predicate.UsageTotal {
+	return predicate.UsageTotal(sql.FieldNotIn(FieldType, vs...))
+}
+
+// TypeGT applies the GT predicate on the "type" field.
+func TypeGT(v int) predicate.UsageTotal {
+	return predicate.UsageTotal(sql.FieldGT(FieldType, v))
+}
+
+// TypeGTE applies the GTE predicate on the "type" field.
+func TypeGTE(v int) predicate.UsageTotal {
+	return predicate.UsageTotal(sql.FieldGTE(FieldType, v))
+}
+
+// TypeLT applies the LT predicate on the "type" field.
+func TypeLT(v int) predicate.UsageTotal {
+	return predicate.UsageTotal(sql.FieldLT(FieldType, v))
+}
+
+// TypeLTE applies the LTE predicate on the "type" field.
+func TypeLTE(v int) predicate.UsageTotal {
+	return predicate.UsageTotal(sql.FieldLTE(FieldType, v))
+}
+
+// TypeIsNil applies the IsNil predicate on the "type" field.
+func TypeIsNil() predicate.UsageTotal {
+	return predicate.UsageTotal(sql.FieldIsNull(FieldType))
+}
+
+// TypeNotNil applies the NotNil predicate on the "type" field.
+func TypeNotNil() predicate.UsageTotal {
+	return predicate.UsageTotal(sql.FieldNotNull(FieldType))
+}
+
+// BotIDEQ applies the EQ predicate on the "bot_id" field.
+func BotIDEQ(v string) predicate.UsageTotal {
+	return predicate.UsageTotal(sql.FieldEQ(FieldBotID, v))
+}
+
+// BotIDNEQ applies the NEQ predicate on the "bot_id" field.
+func BotIDNEQ(v string) predicate.UsageTotal {
+	return predicate.UsageTotal(sql.FieldNEQ(FieldBotID, v))
+}
+
+// BotIDIn applies the In predicate on the "bot_id" field.
+func BotIDIn(vs ...string) predicate.UsageTotal {
+	return predicate.UsageTotal(sql.FieldIn(FieldBotID, vs...))
+}
+
+// BotIDNotIn applies the NotIn predicate on the "bot_id" field.
+func BotIDNotIn(vs ...string) predicate.UsageTotal {
+	return predicate.UsageTotal(sql.FieldNotIn(FieldBotID, vs...))
+}
+
+// BotIDGT applies the GT predicate on the "bot_id" field.
+func BotIDGT(v string) predicate.UsageTotal {
+	return predicate.UsageTotal(sql.FieldGT(FieldBotID, v))
+}
+
+// BotIDGTE applies the GTE predicate on the "bot_id" field.
+func BotIDGTE(v string) predicate.UsageTotal {
+	return predicate.UsageTotal(sql.FieldGTE(FieldBotID, v))
+}
+
+// BotIDLT applies the LT predicate on the "bot_id" field.
+func BotIDLT(v string) predicate.UsageTotal {
+	return predicate.UsageTotal(sql.FieldLT(FieldBotID, v))
+}
+
+// BotIDLTE applies the LTE predicate on the "bot_id" field.
+func BotIDLTE(v string) predicate.UsageTotal {
+	return predicate.UsageTotal(sql.FieldLTE(FieldBotID, v))
+}
+
+// BotIDContains applies the Contains predicate on the "bot_id" field.
+func BotIDContains(v string) predicate.UsageTotal {
+	return predicate.UsageTotal(sql.FieldContains(FieldBotID, v))
+}
+
+// BotIDHasPrefix applies the HasPrefix predicate on the "bot_id" field.
+func BotIDHasPrefix(v string) predicate.UsageTotal {
+	return predicate.UsageTotal(sql.FieldHasPrefix(FieldBotID, v))
+}
+
+// BotIDHasSuffix applies the HasSuffix predicate on the "bot_id" field.
+func BotIDHasSuffix(v string) predicate.UsageTotal {
+	return predicate.UsageTotal(sql.FieldHasSuffix(FieldBotID, v))
+}
+
+// BotIDEqualFold applies the EqualFold predicate on the "bot_id" field.
+func BotIDEqualFold(v string) predicate.UsageTotal {
+	return predicate.UsageTotal(sql.FieldEqualFold(FieldBotID, v))
+}
+
+// BotIDContainsFold applies the ContainsFold predicate on the "bot_id" field.
+func BotIDContainsFold(v string) predicate.UsageTotal {
+	return predicate.UsageTotal(sql.FieldContainsFold(FieldBotID, v))
+}
+
+// TotalTokensEQ applies the EQ predicate on the "total_tokens" field.
+func TotalTokensEQ(v uint64) predicate.UsageTotal {
+	return predicate.UsageTotal(sql.FieldEQ(FieldTotalTokens, v))
+}
+
+// TotalTokensNEQ applies the NEQ predicate on the "total_tokens" field.
+func TotalTokensNEQ(v uint64) predicate.UsageTotal {
+	return predicate.UsageTotal(sql.FieldNEQ(FieldTotalTokens, v))
+}
+
+// TotalTokensIn applies the In predicate on the "total_tokens" field.
+func TotalTokensIn(vs ...uint64) predicate.UsageTotal {
+	return predicate.UsageTotal(sql.FieldIn(FieldTotalTokens, vs...))
+}
+
+// TotalTokensNotIn applies the NotIn predicate on the "total_tokens" field.
+func TotalTokensNotIn(vs ...uint64) predicate.UsageTotal {
+	return predicate.UsageTotal(sql.FieldNotIn(FieldTotalTokens, vs...))
+}
+
+// TotalTokensGT applies the GT predicate on the "total_tokens" field.
+func TotalTokensGT(v uint64) predicate.UsageTotal {
+	return predicate.UsageTotal(sql.FieldGT(FieldTotalTokens, v))
+}
+
+// TotalTokensGTE applies the GTE predicate on the "total_tokens" field.
+func TotalTokensGTE(v uint64) predicate.UsageTotal {
+	return predicate.UsageTotal(sql.FieldGTE(FieldTotalTokens, v))
+}
+
+// TotalTokensLT applies the LT predicate on the "total_tokens" field.
+func TotalTokensLT(v uint64) predicate.UsageTotal {
+	return predicate.UsageTotal(sql.FieldLT(FieldTotalTokens, v))
+}
+
+// TotalTokensLTE applies the LTE predicate on the "total_tokens" field.
+func TotalTokensLTE(v uint64) predicate.UsageTotal {
+	return predicate.UsageTotal(sql.FieldLTE(FieldTotalTokens, v))
+}
+
+// TotalTokensIsNil applies the IsNil predicate on the "total_tokens" field.
+func TotalTokensIsNil() predicate.UsageTotal {
+	return predicate.UsageTotal(sql.FieldIsNull(FieldTotalTokens))
+}
+
+// TotalTokensNotNil applies the NotNil predicate on the "total_tokens" field.
+func TotalTokensNotNil() predicate.UsageTotal {
+	return predicate.UsageTotal(sql.FieldNotNull(FieldTotalTokens))
+}
+
+// StartIndexEQ applies the EQ predicate on the "start_index" field.
+func StartIndexEQ(v uint64) predicate.UsageTotal {
+	return predicate.UsageTotal(sql.FieldEQ(FieldStartIndex, v))
+}
+
+// StartIndexNEQ applies the NEQ predicate on the "start_index" field.
+func StartIndexNEQ(v uint64) predicate.UsageTotal {
+	return predicate.UsageTotal(sql.FieldNEQ(FieldStartIndex, v))
+}
+
+// StartIndexIn applies the In predicate on the "start_index" field.
+func StartIndexIn(vs ...uint64) predicate.UsageTotal {
+	return predicate.UsageTotal(sql.FieldIn(FieldStartIndex, vs...))
+}
+
+// StartIndexNotIn applies the NotIn predicate on the "start_index" field.
+func StartIndexNotIn(vs ...uint64) predicate.UsageTotal {
+	return predicate.UsageTotal(sql.FieldNotIn(FieldStartIndex, vs...))
+}
+
+// StartIndexGT applies the GT predicate on the "start_index" field.
+func StartIndexGT(v uint64) predicate.UsageTotal {
+	return predicate.UsageTotal(sql.FieldGT(FieldStartIndex, v))
+}
+
+// StartIndexGTE applies the GTE predicate on the "start_index" field.
+func StartIndexGTE(v uint64) predicate.UsageTotal {
+	return predicate.UsageTotal(sql.FieldGTE(FieldStartIndex, v))
+}
+
+// StartIndexLT applies the LT predicate on the "start_index" field.
+func StartIndexLT(v uint64) predicate.UsageTotal {
+	return predicate.UsageTotal(sql.FieldLT(FieldStartIndex, v))
+}
+
+// StartIndexLTE applies the LTE predicate on the "start_index" field.
+func StartIndexLTE(v uint64) predicate.UsageTotal {
+	return predicate.UsageTotal(sql.FieldLTE(FieldStartIndex, v))
+}
+
+// StartIndexIsNil applies the IsNil predicate on the "start_index" field.
+func StartIndexIsNil() predicate.UsageTotal {
+	return predicate.UsageTotal(sql.FieldIsNull(FieldStartIndex))
+}
+
+// StartIndexNotNil applies the NotNil predicate on the "start_index" field.
+func StartIndexNotNil() predicate.UsageTotal {
+	return predicate.UsageTotal(sql.FieldNotNull(FieldStartIndex))
+}
+
+// EndIndexEQ applies the EQ predicate on the "end_index" field.
+func EndIndexEQ(v uint64) predicate.UsageTotal {
+	return predicate.UsageTotal(sql.FieldEQ(FieldEndIndex, v))
+}
+
+// EndIndexNEQ applies the NEQ predicate on the "end_index" field.
+func EndIndexNEQ(v uint64) predicate.UsageTotal {
+	return predicate.UsageTotal(sql.FieldNEQ(FieldEndIndex, v))
+}
+
+// EndIndexIn applies the In predicate on the "end_index" field.
+func EndIndexIn(vs ...uint64) predicate.UsageTotal {
+	return predicate.UsageTotal(sql.FieldIn(FieldEndIndex, vs...))
+}
+
+// EndIndexNotIn applies the NotIn predicate on the "end_index" field.
+func EndIndexNotIn(vs ...uint64) predicate.UsageTotal {
+	return predicate.UsageTotal(sql.FieldNotIn(FieldEndIndex, vs...))
+}
+
+// EndIndexGT applies the GT predicate on the "end_index" field.
+func EndIndexGT(v uint64) predicate.UsageTotal {
+	return predicate.UsageTotal(sql.FieldGT(FieldEndIndex, v))
+}
+
+// EndIndexGTE applies the GTE predicate on the "end_index" field.
+func EndIndexGTE(v uint64) predicate.UsageTotal {
+	return predicate.UsageTotal(sql.FieldGTE(FieldEndIndex, v))
+}
+
+// EndIndexLT applies the LT predicate on the "end_index" field.
+func EndIndexLT(v uint64) predicate.UsageTotal {
+	return predicate.UsageTotal(sql.FieldLT(FieldEndIndex, v))
+}
+
+// EndIndexLTE applies the LTE predicate on the "end_index" field.
+func EndIndexLTE(v uint64) predicate.UsageTotal {
+	return predicate.UsageTotal(sql.FieldLTE(FieldEndIndex, v))
+}
+
+// EndIndexIsNil applies the IsNil predicate on the "end_index" field.
+func EndIndexIsNil() predicate.UsageTotal {
+	return predicate.UsageTotal(sql.FieldIsNull(FieldEndIndex))
+}
+
+// EndIndexNotNil applies the NotNil predicate on the "end_index" field.
+func EndIndexNotNil() predicate.UsageTotal {
+	return predicate.UsageTotal(sql.FieldNotNull(FieldEndIndex))
+}
+
+// OrganizationIDEQ applies the EQ predicate on the "organization_id" field.
+func OrganizationIDEQ(v uint64) predicate.UsageTotal {
+	return predicate.UsageTotal(sql.FieldEQ(FieldOrganizationID, v))
+}
+
+// OrganizationIDNEQ applies the NEQ predicate on the "organization_id" field.
+func OrganizationIDNEQ(v uint64) predicate.UsageTotal {
+	return predicate.UsageTotal(sql.FieldNEQ(FieldOrganizationID, v))
+}
+
+// OrganizationIDIn applies the In predicate on the "organization_id" field.
+func OrganizationIDIn(vs ...uint64) predicate.UsageTotal {
+	return predicate.UsageTotal(sql.FieldIn(FieldOrganizationID, vs...))
+}
+
+// OrganizationIDNotIn applies the NotIn predicate on the "organization_id" field.
+func OrganizationIDNotIn(vs ...uint64) predicate.UsageTotal {
+	return predicate.UsageTotal(sql.FieldNotIn(FieldOrganizationID, vs...))
+}
+
+// OrganizationIDGT applies the GT predicate on the "organization_id" field.
+func OrganizationIDGT(v uint64) predicate.UsageTotal {
+	return predicate.UsageTotal(sql.FieldGT(FieldOrganizationID, v))
+}
+
+// OrganizationIDGTE applies the GTE predicate on the "organization_id" field.
+func OrganizationIDGTE(v uint64) predicate.UsageTotal {
+	return predicate.UsageTotal(sql.FieldGTE(FieldOrganizationID, v))
+}
+
+// OrganizationIDLT applies the LT predicate on the "organization_id" field.
+func OrganizationIDLT(v uint64) predicate.UsageTotal {
+	return predicate.UsageTotal(sql.FieldLT(FieldOrganizationID, v))
+}
+
+// OrganizationIDLTE applies the LTE predicate on the "organization_id" field.
+func OrganizationIDLTE(v uint64) predicate.UsageTotal {
+	return predicate.UsageTotal(sql.FieldLTE(FieldOrganizationID, v))
+}
+
+// OrganizationIDIsNil applies the IsNil predicate on the "organization_id" field.
+func OrganizationIDIsNil() predicate.UsageTotal {
+	return predicate.UsageTotal(sql.FieldIsNull(FieldOrganizationID))
+}
+
+// OrganizationIDNotNil applies the NotNil predicate on the "organization_id" field.
+func OrganizationIDNotNil() predicate.UsageTotal {
+	return predicate.UsageTotal(sql.FieldNotNull(FieldOrganizationID))
+}
+
+// And groups predicates with the AND operator between them.
+func And(predicates ...predicate.UsageTotal) predicate.UsageTotal {
+	return predicate.UsageTotal(sql.AndPredicates(predicates...))
+}
+
+// Or groups predicates with the OR operator between them.
+func Or(predicates ...predicate.UsageTotal) predicate.UsageTotal {
+	return predicate.UsageTotal(sql.OrPredicates(predicates...))
+}
+
+// Not applies the not operator on the given predicate.
+func Not(p predicate.UsageTotal) predicate.UsageTotal {
+	return predicate.UsageTotal(sql.NotPredicates(p))
+}

+ 1211 - 0
ent/usagetotal_create.go

@@ -0,0 +1,1211 @@
+// Code generated by ent, DO NOT EDIT.
+
+package ent
+
+import (
+	"context"
+	"errors"
+	"fmt"
+	"time"
+	"wechat-api/ent/usagetotal"
+
+	"entgo.io/ent/dialect/sql"
+	"entgo.io/ent/dialect/sql/sqlgraph"
+	"entgo.io/ent/schema/field"
+)
+
+// UsageTotalCreate is the builder for creating a UsageTotal entity.
+type UsageTotalCreate struct {
+	config
+	mutation *UsageTotalMutation
+	hooks    []Hook
+	conflict []sql.ConflictOption
+}
+
+// SetCreatedAt sets the "created_at" field.
+func (utc *UsageTotalCreate) SetCreatedAt(t time.Time) *UsageTotalCreate {
+	utc.mutation.SetCreatedAt(t)
+	return utc
+}
+
+// SetNillableCreatedAt sets the "created_at" field if the given value is not nil.
+func (utc *UsageTotalCreate) SetNillableCreatedAt(t *time.Time) *UsageTotalCreate {
+	if t != nil {
+		utc.SetCreatedAt(*t)
+	}
+	return utc
+}
+
+// SetUpdatedAt sets the "updated_at" field.
+func (utc *UsageTotalCreate) SetUpdatedAt(t time.Time) *UsageTotalCreate {
+	utc.mutation.SetUpdatedAt(t)
+	return utc
+}
+
+// SetNillableUpdatedAt sets the "updated_at" field if the given value is not nil.
+func (utc *UsageTotalCreate) SetNillableUpdatedAt(t *time.Time) *UsageTotalCreate {
+	if t != nil {
+		utc.SetUpdatedAt(*t)
+	}
+	return utc
+}
+
+// SetStatus sets the "status" field.
+func (utc *UsageTotalCreate) SetStatus(u uint8) *UsageTotalCreate {
+	utc.mutation.SetStatus(u)
+	return utc
+}
+
+// SetNillableStatus sets the "status" field if the given value is not nil.
+func (utc *UsageTotalCreate) SetNillableStatus(u *uint8) *UsageTotalCreate {
+	if u != nil {
+		utc.SetStatus(*u)
+	}
+	return utc
+}
+
+// SetType sets the "type" field.
+func (utc *UsageTotalCreate) SetType(i int) *UsageTotalCreate {
+	utc.mutation.SetType(i)
+	return utc
+}
+
+// SetNillableType sets the "type" field if the given value is not nil.
+func (utc *UsageTotalCreate) SetNillableType(i *int) *UsageTotalCreate {
+	if i != nil {
+		utc.SetType(*i)
+	}
+	return utc
+}
+
+// SetBotID sets the "bot_id" field.
+func (utc *UsageTotalCreate) SetBotID(s string) *UsageTotalCreate {
+	utc.mutation.SetBotID(s)
+	return utc
+}
+
+// SetNillableBotID sets the "bot_id" field if the given value is not nil.
+func (utc *UsageTotalCreate) SetNillableBotID(s *string) *UsageTotalCreate {
+	if s != nil {
+		utc.SetBotID(*s)
+	}
+	return utc
+}
+
+// SetTotalTokens sets the "total_tokens" field.
+func (utc *UsageTotalCreate) SetTotalTokens(u uint64) *UsageTotalCreate {
+	utc.mutation.SetTotalTokens(u)
+	return utc
+}
+
+// SetNillableTotalTokens sets the "total_tokens" field if the given value is not nil.
+func (utc *UsageTotalCreate) SetNillableTotalTokens(u *uint64) *UsageTotalCreate {
+	if u != nil {
+		utc.SetTotalTokens(*u)
+	}
+	return utc
+}
+
+// SetStartIndex sets the "start_index" field.
+func (utc *UsageTotalCreate) SetStartIndex(u uint64) *UsageTotalCreate {
+	utc.mutation.SetStartIndex(u)
+	return utc
+}
+
+// SetNillableStartIndex sets the "start_index" field if the given value is not nil.
+func (utc *UsageTotalCreate) SetNillableStartIndex(u *uint64) *UsageTotalCreate {
+	if u != nil {
+		utc.SetStartIndex(*u)
+	}
+	return utc
+}
+
+// SetEndIndex sets the "end_index" field.
+func (utc *UsageTotalCreate) SetEndIndex(u uint64) *UsageTotalCreate {
+	utc.mutation.SetEndIndex(u)
+	return utc
+}
+
+// SetNillableEndIndex sets the "end_index" field if the given value is not nil.
+func (utc *UsageTotalCreate) SetNillableEndIndex(u *uint64) *UsageTotalCreate {
+	if u != nil {
+		utc.SetEndIndex(*u)
+	}
+	return utc
+}
+
+// SetOrganizationID sets the "organization_id" field.
+func (utc *UsageTotalCreate) SetOrganizationID(u uint64) *UsageTotalCreate {
+	utc.mutation.SetOrganizationID(u)
+	return utc
+}
+
+// SetNillableOrganizationID sets the "organization_id" field if the given value is not nil.
+func (utc *UsageTotalCreate) SetNillableOrganizationID(u *uint64) *UsageTotalCreate {
+	if u != nil {
+		utc.SetOrganizationID(*u)
+	}
+	return utc
+}
+
+// SetID sets the "id" field.
+func (utc *UsageTotalCreate) SetID(u uint64) *UsageTotalCreate {
+	utc.mutation.SetID(u)
+	return utc
+}
+
+// Mutation returns the UsageTotalMutation object of the builder.
+func (utc *UsageTotalCreate) Mutation() *UsageTotalMutation {
+	return utc.mutation
+}
+
+// Save creates the UsageTotal in the database.
+func (utc *UsageTotalCreate) Save(ctx context.Context) (*UsageTotal, error) {
+	utc.defaults()
+	return withHooks(ctx, utc.sqlSave, utc.mutation, utc.hooks)
+}
+
+// SaveX calls Save and panics if Save returns an error.
+func (utc *UsageTotalCreate) SaveX(ctx context.Context) *UsageTotal {
+	v, err := utc.Save(ctx)
+	if err != nil {
+		panic(err)
+	}
+	return v
+}
+
+// Exec executes the query.
+func (utc *UsageTotalCreate) Exec(ctx context.Context) error {
+	_, err := utc.Save(ctx)
+	return err
+}
+
+// ExecX is like Exec, but panics if an error occurs.
+func (utc *UsageTotalCreate) ExecX(ctx context.Context) {
+	if err := utc.Exec(ctx); err != nil {
+		panic(err)
+	}
+}
+
+// defaults sets the default values of the builder before save.
+func (utc *UsageTotalCreate) defaults() {
+	if _, ok := utc.mutation.CreatedAt(); !ok {
+		v := usagetotal.DefaultCreatedAt()
+		utc.mutation.SetCreatedAt(v)
+	}
+	if _, ok := utc.mutation.UpdatedAt(); !ok {
+		v := usagetotal.DefaultUpdatedAt()
+		utc.mutation.SetUpdatedAt(v)
+	}
+	if _, ok := utc.mutation.Status(); !ok {
+		v := usagetotal.DefaultStatus
+		utc.mutation.SetStatus(v)
+	}
+	if _, ok := utc.mutation.GetType(); !ok {
+		v := usagetotal.DefaultType
+		utc.mutation.SetType(v)
+	}
+	if _, ok := utc.mutation.BotID(); !ok {
+		v := usagetotal.DefaultBotID
+		utc.mutation.SetBotID(v)
+	}
+	if _, ok := utc.mutation.TotalTokens(); !ok {
+		v := usagetotal.DefaultTotalTokens
+		utc.mutation.SetTotalTokens(v)
+	}
+	if _, ok := utc.mutation.StartIndex(); !ok {
+		v := usagetotal.DefaultStartIndex
+		utc.mutation.SetStartIndex(v)
+	}
+	if _, ok := utc.mutation.EndIndex(); !ok {
+		v := usagetotal.DefaultEndIndex
+		utc.mutation.SetEndIndex(v)
+	}
+	if _, ok := utc.mutation.OrganizationID(); !ok {
+		v := usagetotal.DefaultOrganizationID
+		utc.mutation.SetOrganizationID(v)
+	}
+}
+
+// check runs all checks and user-defined validators on the builder.
+func (utc *UsageTotalCreate) check() error {
+	if _, ok := utc.mutation.CreatedAt(); !ok {
+		return &ValidationError{Name: "created_at", err: errors.New(`ent: missing required field "UsageTotal.created_at"`)}
+	}
+	if _, ok := utc.mutation.UpdatedAt(); !ok {
+		return &ValidationError{Name: "updated_at", err: errors.New(`ent: missing required field "UsageTotal.updated_at"`)}
+	}
+	if _, ok := utc.mutation.BotID(); !ok {
+		return &ValidationError{Name: "bot_id", err: errors.New(`ent: missing required field "UsageTotal.bot_id"`)}
+	}
+	return nil
+}
+
+func (utc *UsageTotalCreate) sqlSave(ctx context.Context) (*UsageTotal, error) {
+	if err := utc.check(); err != nil {
+		return nil, err
+	}
+	_node, _spec := utc.createSpec()
+	if err := sqlgraph.CreateNode(ctx, utc.driver, _spec); err != nil {
+		if sqlgraph.IsConstraintError(err) {
+			err = &ConstraintError{msg: err.Error(), wrap: err}
+		}
+		return nil, err
+	}
+	if _spec.ID.Value != _node.ID {
+		id := _spec.ID.Value.(int64)
+		_node.ID = uint64(id)
+	}
+	utc.mutation.id = &_node.ID
+	utc.mutation.done = true
+	return _node, nil
+}
+
+func (utc *UsageTotalCreate) createSpec() (*UsageTotal, *sqlgraph.CreateSpec) {
+	var (
+		_node = &UsageTotal{config: utc.config}
+		_spec = sqlgraph.NewCreateSpec(usagetotal.Table, sqlgraph.NewFieldSpec(usagetotal.FieldID, field.TypeUint64))
+	)
+	_spec.OnConflict = utc.conflict
+	if id, ok := utc.mutation.ID(); ok {
+		_node.ID = id
+		_spec.ID.Value = id
+	}
+	if value, ok := utc.mutation.CreatedAt(); ok {
+		_spec.SetField(usagetotal.FieldCreatedAt, field.TypeTime, value)
+		_node.CreatedAt = value
+	}
+	if value, ok := utc.mutation.UpdatedAt(); ok {
+		_spec.SetField(usagetotal.FieldUpdatedAt, field.TypeTime, value)
+		_node.UpdatedAt = value
+	}
+	if value, ok := utc.mutation.Status(); ok {
+		_spec.SetField(usagetotal.FieldStatus, field.TypeUint8, value)
+		_node.Status = value
+	}
+	if value, ok := utc.mutation.GetType(); ok {
+		_spec.SetField(usagetotal.FieldType, field.TypeInt, value)
+		_node.Type = value
+	}
+	if value, ok := utc.mutation.BotID(); ok {
+		_spec.SetField(usagetotal.FieldBotID, field.TypeString, value)
+		_node.BotID = value
+	}
+	if value, ok := utc.mutation.TotalTokens(); ok {
+		_spec.SetField(usagetotal.FieldTotalTokens, field.TypeUint64, value)
+		_node.TotalTokens = value
+	}
+	if value, ok := utc.mutation.StartIndex(); ok {
+		_spec.SetField(usagetotal.FieldStartIndex, field.TypeUint64, value)
+		_node.StartIndex = value
+	}
+	if value, ok := utc.mutation.EndIndex(); ok {
+		_spec.SetField(usagetotal.FieldEndIndex, field.TypeUint64, value)
+		_node.EndIndex = value
+	}
+	if value, ok := utc.mutation.OrganizationID(); ok {
+		_spec.SetField(usagetotal.FieldOrganizationID, field.TypeUint64, value)
+		_node.OrganizationID = value
+	}
+	return _node, _spec
+}
+
+// OnConflict allows configuring the `ON CONFLICT` / `ON DUPLICATE KEY` clause
+// of the `INSERT` statement. For example:
+//
+//	client.UsageTotal.Create().
+//		SetCreatedAt(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.UsageTotalUpsert) {
+//			SetCreatedAt(v+v).
+//		}).
+//		Exec(ctx)
+func (utc *UsageTotalCreate) OnConflict(opts ...sql.ConflictOption) *UsageTotalUpsertOne {
+	utc.conflict = opts
+	return &UsageTotalUpsertOne{
+		create: utc,
+	}
+}
+
+// OnConflictColumns calls `OnConflict` and configures the columns
+// as conflict target. Using this option is equivalent to using:
+//
+//	client.UsageTotal.Create().
+//		OnConflict(sql.ConflictColumns(columns...)).
+//		Exec(ctx)
+func (utc *UsageTotalCreate) OnConflictColumns(columns ...string) *UsageTotalUpsertOne {
+	utc.conflict = append(utc.conflict, sql.ConflictColumns(columns...))
+	return &UsageTotalUpsertOne{
+		create: utc,
+	}
+}
+
+type (
+	// UsageTotalUpsertOne is the builder for "upsert"-ing
+	//  one UsageTotal node.
+	UsageTotalUpsertOne struct {
+		create *UsageTotalCreate
+	}
+
+	// UsageTotalUpsert is the "OnConflict" setter.
+	UsageTotalUpsert struct {
+		*sql.UpdateSet
+	}
+)
+
+// SetUpdatedAt sets the "updated_at" field.
+func (u *UsageTotalUpsert) SetUpdatedAt(v time.Time) *UsageTotalUpsert {
+	u.Set(usagetotal.FieldUpdatedAt, v)
+	return u
+}
+
+// UpdateUpdatedAt sets the "updated_at" field to the value that was provided on create.
+func (u *UsageTotalUpsert) UpdateUpdatedAt() *UsageTotalUpsert {
+	u.SetExcluded(usagetotal.FieldUpdatedAt)
+	return u
+}
+
+// SetStatus sets the "status" field.
+func (u *UsageTotalUpsert) SetStatus(v uint8) *UsageTotalUpsert {
+	u.Set(usagetotal.FieldStatus, v)
+	return u
+}
+
+// UpdateStatus sets the "status" field to the value that was provided on create.
+func (u *UsageTotalUpsert) UpdateStatus() *UsageTotalUpsert {
+	u.SetExcluded(usagetotal.FieldStatus)
+	return u
+}
+
+// AddStatus adds v to the "status" field.
+func (u *UsageTotalUpsert) AddStatus(v uint8) *UsageTotalUpsert {
+	u.Add(usagetotal.FieldStatus, v)
+	return u
+}
+
+// ClearStatus clears the value of the "status" field.
+func (u *UsageTotalUpsert) ClearStatus() *UsageTotalUpsert {
+	u.SetNull(usagetotal.FieldStatus)
+	return u
+}
+
+// SetType sets the "type" field.
+func (u *UsageTotalUpsert) SetType(v int) *UsageTotalUpsert {
+	u.Set(usagetotal.FieldType, v)
+	return u
+}
+
+// UpdateType sets the "type" field to the value that was provided on create.
+func (u *UsageTotalUpsert) UpdateType() *UsageTotalUpsert {
+	u.SetExcluded(usagetotal.FieldType)
+	return u
+}
+
+// AddType adds v to the "type" field.
+func (u *UsageTotalUpsert) AddType(v int) *UsageTotalUpsert {
+	u.Add(usagetotal.FieldType, v)
+	return u
+}
+
+// ClearType clears the value of the "type" field.
+func (u *UsageTotalUpsert) ClearType() *UsageTotalUpsert {
+	u.SetNull(usagetotal.FieldType)
+	return u
+}
+
+// SetBotID sets the "bot_id" field.
+func (u *UsageTotalUpsert) SetBotID(v string) *UsageTotalUpsert {
+	u.Set(usagetotal.FieldBotID, v)
+	return u
+}
+
+// UpdateBotID sets the "bot_id" field to the value that was provided on create.
+func (u *UsageTotalUpsert) UpdateBotID() *UsageTotalUpsert {
+	u.SetExcluded(usagetotal.FieldBotID)
+	return u
+}
+
+// SetTotalTokens sets the "total_tokens" field.
+func (u *UsageTotalUpsert) SetTotalTokens(v uint64) *UsageTotalUpsert {
+	u.Set(usagetotal.FieldTotalTokens, v)
+	return u
+}
+
+// UpdateTotalTokens sets the "total_tokens" field to the value that was provided on create.
+func (u *UsageTotalUpsert) UpdateTotalTokens() *UsageTotalUpsert {
+	u.SetExcluded(usagetotal.FieldTotalTokens)
+	return u
+}
+
+// AddTotalTokens adds v to the "total_tokens" field.
+func (u *UsageTotalUpsert) AddTotalTokens(v uint64) *UsageTotalUpsert {
+	u.Add(usagetotal.FieldTotalTokens, v)
+	return u
+}
+
+// ClearTotalTokens clears the value of the "total_tokens" field.
+func (u *UsageTotalUpsert) ClearTotalTokens() *UsageTotalUpsert {
+	u.SetNull(usagetotal.FieldTotalTokens)
+	return u
+}
+
+// SetStartIndex sets the "start_index" field.
+func (u *UsageTotalUpsert) SetStartIndex(v uint64) *UsageTotalUpsert {
+	u.Set(usagetotal.FieldStartIndex, v)
+	return u
+}
+
+// UpdateStartIndex sets the "start_index" field to the value that was provided on create.
+func (u *UsageTotalUpsert) UpdateStartIndex() *UsageTotalUpsert {
+	u.SetExcluded(usagetotal.FieldStartIndex)
+	return u
+}
+
+// AddStartIndex adds v to the "start_index" field.
+func (u *UsageTotalUpsert) AddStartIndex(v uint64) *UsageTotalUpsert {
+	u.Add(usagetotal.FieldStartIndex, v)
+	return u
+}
+
+// ClearStartIndex clears the value of the "start_index" field.
+func (u *UsageTotalUpsert) ClearStartIndex() *UsageTotalUpsert {
+	u.SetNull(usagetotal.FieldStartIndex)
+	return u
+}
+
+// SetEndIndex sets the "end_index" field.
+func (u *UsageTotalUpsert) SetEndIndex(v uint64) *UsageTotalUpsert {
+	u.Set(usagetotal.FieldEndIndex, v)
+	return u
+}
+
+// UpdateEndIndex sets the "end_index" field to the value that was provided on create.
+func (u *UsageTotalUpsert) UpdateEndIndex() *UsageTotalUpsert {
+	u.SetExcluded(usagetotal.FieldEndIndex)
+	return u
+}
+
+// AddEndIndex adds v to the "end_index" field.
+func (u *UsageTotalUpsert) AddEndIndex(v uint64) *UsageTotalUpsert {
+	u.Add(usagetotal.FieldEndIndex, v)
+	return u
+}
+
+// ClearEndIndex clears the value of the "end_index" field.
+func (u *UsageTotalUpsert) ClearEndIndex() *UsageTotalUpsert {
+	u.SetNull(usagetotal.FieldEndIndex)
+	return u
+}
+
+// SetOrganizationID sets the "organization_id" field.
+func (u *UsageTotalUpsert) SetOrganizationID(v uint64) *UsageTotalUpsert {
+	u.Set(usagetotal.FieldOrganizationID, v)
+	return u
+}
+
+// UpdateOrganizationID sets the "organization_id" field to the value that was provided on create.
+func (u *UsageTotalUpsert) UpdateOrganizationID() *UsageTotalUpsert {
+	u.SetExcluded(usagetotal.FieldOrganizationID)
+	return u
+}
+
+// AddOrganizationID adds v to the "organization_id" field.
+func (u *UsageTotalUpsert) AddOrganizationID(v uint64) *UsageTotalUpsert {
+	u.Add(usagetotal.FieldOrganizationID, v)
+	return u
+}
+
+// ClearOrganizationID clears the value of the "organization_id" field.
+func (u *UsageTotalUpsert) ClearOrganizationID() *UsageTotalUpsert {
+	u.SetNull(usagetotal.FieldOrganizationID)
+	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.UsageTotal.Create().
+//		OnConflict(
+//			sql.ResolveWithNewValues(),
+//			sql.ResolveWith(func(u *sql.UpdateSet) {
+//				u.SetIgnore(usagetotal.FieldID)
+//			}),
+//		).
+//		Exec(ctx)
+func (u *UsageTotalUpsertOne) UpdateNewValues() *UsageTotalUpsertOne {
+	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(usagetotal.FieldID)
+		}
+		if _, exists := u.create.mutation.CreatedAt(); exists {
+			s.SetIgnore(usagetotal.FieldCreatedAt)
+		}
+	}))
+	return u
+}
+
+// Ignore sets each column to itself in case of conflict.
+// Using this option is equivalent to using:
+//
+//	client.UsageTotal.Create().
+//	    OnConflict(sql.ResolveWithIgnore()).
+//	    Exec(ctx)
+func (u *UsageTotalUpsertOne) Ignore() *UsageTotalUpsertOne {
+	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 *UsageTotalUpsertOne) DoNothing() *UsageTotalUpsertOne {
+	u.create.conflict = append(u.create.conflict, sql.DoNothing())
+	return u
+}
+
+// Update allows overriding fields `UPDATE` values. See the UsageTotalCreate.OnConflict
+// documentation for more info.
+func (u *UsageTotalUpsertOne) Update(set func(*UsageTotalUpsert)) *UsageTotalUpsertOne {
+	u.create.conflict = append(u.create.conflict, sql.ResolveWith(func(update *sql.UpdateSet) {
+		set(&UsageTotalUpsert{UpdateSet: update})
+	}))
+	return u
+}
+
+// SetUpdatedAt sets the "updated_at" field.
+func (u *UsageTotalUpsertOne) SetUpdatedAt(v time.Time) *UsageTotalUpsertOne {
+	return u.Update(func(s *UsageTotalUpsert) {
+		s.SetUpdatedAt(v)
+	})
+}
+
+// UpdateUpdatedAt sets the "updated_at" field to the value that was provided on create.
+func (u *UsageTotalUpsertOne) UpdateUpdatedAt() *UsageTotalUpsertOne {
+	return u.Update(func(s *UsageTotalUpsert) {
+		s.UpdateUpdatedAt()
+	})
+}
+
+// SetStatus sets the "status" field.
+func (u *UsageTotalUpsertOne) SetStatus(v uint8) *UsageTotalUpsertOne {
+	return u.Update(func(s *UsageTotalUpsert) {
+		s.SetStatus(v)
+	})
+}
+
+// AddStatus adds v to the "status" field.
+func (u *UsageTotalUpsertOne) AddStatus(v uint8) *UsageTotalUpsertOne {
+	return u.Update(func(s *UsageTotalUpsert) {
+		s.AddStatus(v)
+	})
+}
+
+// UpdateStatus sets the "status" field to the value that was provided on create.
+func (u *UsageTotalUpsertOne) UpdateStatus() *UsageTotalUpsertOne {
+	return u.Update(func(s *UsageTotalUpsert) {
+		s.UpdateStatus()
+	})
+}
+
+// ClearStatus clears the value of the "status" field.
+func (u *UsageTotalUpsertOne) ClearStatus() *UsageTotalUpsertOne {
+	return u.Update(func(s *UsageTotalUpsert) {
+		s.ClearStatus()
+	})
+}
+
+// SetType sets the "type" field.
+func (u *UsageTotalUpsertOne) SetType(v int) *UsageTotalUpsertOne {
+	return u.Update(func(s *UsageTotalUpsert) {
+		s.SetType(v)
+	})
+}
+
+// AddType adds v to the "type" field.
+func (u *UsageTotalUpsertOne) AddType(v int) *UsageTotalUpsertOne {
+	return u.Update(func(s *UsageTotalUpsert) {
+		s.AddType(v)
+	})
+}
+
+// UpdateType sets the "type" field to the value that was provided on create.
+func (u *UsageTotalUpsertOne) UpdateType() *UsageTotalUpsertOne {
+	return u.Update(func(s *UsageTotalUpsert) {
+		s.UpdateType()
+	})
+}
+
+// ClearType clears the value of the "type" field.
+func (u *UsageTotalUpsertOne) ClearType() *UsageTotalUpsertOne {
+	return u.Update(func(s *UsageTotalUpsert) {
+		s.ClearType()
+	})
+}
+
+// SetBotID sets the "bot_id" field.
+func (u *UsageTotalUpsertOne) SetBotID(v string) *UsageTotalUpsertOne {
+	return u.Update(func(s *UsageTotalUpsert) {
+		s.SetBotID(v)
+	})
+}
+
+// UpdateBotID sets the "bot_id" field to the value that was provided on create.
+func (u *UsageTotalUpsertOne) UpdateBotID() *UsageTotalUpsertOne {
+	return u.Update(func(s *UsageTotalUpsert) {
+		s.UpdateBotID()
+	})
+}
+
+// SetTotalTokens sets the "total_tokens" field.
+func (u *UsageTotalUpsertOne) SetTotalTokens(v uint64) *UsageTotalUpsertOne {
+	return u.Update(func(s *UsageTotalUpsert) {
+		s.SetTotalTokens(v)
+	})
+}
+
+// AddTotalTokens adds v to the "total_tokens" field.
+func (u *UsageTotalUpsertOne) AddTotalTokens(v uint64) *UsageTotalUpsertOne {
+	return u.Update(func(s *UsageTotalUpsert) {
+		s.AddTotalTokens(v)
+	})
+}
+
+// UpdateTotalTokens sets the "total_tokens" field to the value that was provided on create.
+func (u *UsageTotalUpsertOne) UpdateTotalTokens() *UsageTotalUpsertOne {
+	return u.Update(func(s *UsageTotalUpsert) {
+		s.UpdateTotalTokens()
+	})
+}
+
+// ClearTotalTokens clears the value of the "total_tokens" field.
+func (u *UsageTotalUpsertOne) ClearTotalTokens() *UsageTotalUpsertOne {
+	return u.Update(func(s *UsageTotalUpsert) {
+		s.ClearTotalTokens()
+	})
+}
+
+// SetStartIndex sets the "start_index" field.
+func (u *UsageTotalUpsertOne) SetStartIndex(v uint64) *UsageTotalUpsertOne {
+	return u.Update(func(s *UsageTotalUpsert) {
+		s.SetStartIndex(v)
+	})
+}
+
+// AddStartIndex adds v to the "start_index" field.
+func (u *UsageTotalUpsertOne) AddStartIndex(v uint64) *UsageTotalUpsertOne {
+	return u.Update(func(s *UsageTotalUpsert) {
+		s.AddStartIndex(v)
+	})
+}
+
+// UpdateStartIndex sets the "start_index" field to the value that was provided on create.
+func (u *UsageTotalUpsertOne) UpdateStartIndex() *UsageTotalUpsertOne {
+	return u.Update(func(s *UsageTotalUpsert) {
+		s.UpdateStartIndex()
+	})
+}
+
+// ClearStartIndex clears the value of the "start_index" field.
+func (u *UsageTotalUpsertOne) ClearStartIndex() *UsageTotalUpsertOne {
+	return u.Update(func(s *UsageTotalUpsert) {
+		s.ClearStartIndex()
+	})
+}
+
+// SetEndIndex sets the "end_index" field.
+func (u *UsageTotalUpsertOne) SetEndIndex(v uint64) *UsageTotalUpsertOne {
+	return u.Update(func(s *UsageTotalUpsert) {
+		s.SetEndIndex(v)
+	})
+}
+
+// AddEndIndex adds v to the "end_index" field.
+func (u *UsageTotalUpsertOne) AddEndIndex(v uint64) *UsageTotalUpsertOne {
+	return u.Update(func(s *UsageTotalUpsert) {
+		s.AddEndIndex(v)
+	})
+}
+
+// UpdateEndIndex sets the "end_index" field to the value that was provided on create.
+func (u *UsageTotalUpsertOne) UpdateEndIndex() *UsageTotalUpsertOne {
+	return u.Update(func(s *UsageTotalUpsert) {
+		s.UpdateEndIndex()
+	})
+}
+
+// ClearEndIndex clears the value of the "end_index" field.
+func (u *UsageTotalUpsertOne) ClearEndIndex() *UsageTotalUpsertOne {
+	return u.Update(func(s *UsageTotalUpsert) {
+		s.ClearEndIndex()
+	})
+}
+
+// SetOrganizationID sets the "organization_id" field.
+func (u *UsageTotalUpsertOne) SetOrganizationID(v uint64) *UsageTotalUpsertOne {
+	return u.Update(func(s *UsageTotalUpsert) {
+		s.SetOrganizationID(v)
+	})
+}
+
+// AddOrganizationID adds v to the "organization_id" field.
+func (u *UsageTotalUpsertOne) AddOrganizationID(v uint64) *UsageTotalUpsertOne {
+	return u.Update(func(s *UsageTotalUpsert) {
+		s.AddOrganizationID(v)
+	})
+}
+
+// UpdateOrganizationID sets the "organization_id" field to the value that was provided on create.
+func (u *UsageTotalUpsertOne) UpdateOrganizationID() *UsageTotalUpsertOne {
+	return u.Update(func(s *UsageTotalUpsert) {
+		s.UpdateOrganizationID()
+	})
+}
+
+// ClearOrganizationID clears the value of the "organization_id" field.
+func (u *UsageTotalUpsertOne) ClearOrganizationID() *UsageTotalUpsertOne {
+	return u.Update(func(s *UsageTotalUpsert) {
+		s.ClearOrganizationID()
+	})
+}
+
+// Exec executes the query.
+func (u *UsageTotalUpsertOne) Exec(ctx context.Context) error {
+	if len(u.create.conflict) == 0 {
+		return errors.New("ent: missing options for UsageTotalCreate.OnConflict")
+	}
+	return u.create.Exec(ctx)
+}
+
+// ExecX is like Exec, but panics if an error occurs.
+func (u *UsageTotalUpsertOne) 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 *UsageTotalUpsertOne) ID(ctx context.Context) (id uint64, err error) {
+	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 *UsageTotalUpsertOne) IDX(ctx context.Context) uint64 {
+	id, err := u.ID(ctx)
+	if err != nil {
+		panic(err)
+	}
+	return id
+}
+
+// UsageTotalCreateBulk is the builder for creating many UsageTotal entities in bulk.
+type UsageTotalCreateBulk struct {
+	config
+	err      error
+	builders []*UsageTotalCreate
+	conflict []sql.ConflictOption
+}
+
+// Save creates the UsageTotal entities in the database.
+func (utcb *UsageTotalCreateBulk) Save(ctx context.Context) ([]*UsageTotal, error) {
+	if utcb.err != nil {
+		return nil, utcb.err
+	}
+	specs := make([]*sqlgraph.CreateSpec, len(utcb.builders))
+	nodes := make([]*UsageTotal, len(utcb.builders))
+	mutators := make([]Mutator, len(utcb.builders))
+	for i := range utcb.builders {
+		func(i int, root context.Context) {
+			builder := utcb.builders[i]
+			builder.defaults()
+			var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) {
+				mutation, ok := m.(*UsageTotalMutation)
+				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, utcb.builders[i+1].mutation)
+				} else {
+					spec := &sqlgraph.BatchCreateSpec{Nodes: specs}
+					spec.OnConflict = utcb.conflict
+					// Invoke the actual operation on the latest mutation in the chain.
+					if err = sqlgraph.BatchCreate(ctx, utcb.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
+				if specs[i].ID.Value != nil && nodes[i].ID == 0 {
+					id := specs[i].ID.Value.(int64)
+					nodes[i].ID = uint64(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, utcb.builders[0].mutation); err != nil {
+			return nil, err
+		}
+	}
+	return nodes, nil
+}
+
+// SaveX is like Save, but panics if an error occurs.
+func (utcb *UsageTotalCreateBulk) SaveX(ctx context.Context) []*UsageTotal {
+	v, err := utcb.Save(ctx)
+	if err != nil {
+		panic(err)
+	}
+	return v
+}
+
+// Exec executes the query.
+func (utcb *UsageTotalCreateBulk) Exec(ctx context.Context) error {
+	_, err := utcb.Save(ctx)
+	return err
+}
+
+// ExecX is like Exec, but panics if an error occurs.
+func (utcb *UsageTotalCreateBulk) ExecX(ctx context.Context) {
+	if err := utcb.Exec(ctx); err != nil {
+		panic(err)
+	}
+}
+
+// OnConflict allows configuring the `ON CONFLICT` / `ON DUPLICATE KEY` clause
+// of the `INSERT` statement. For example:
+//
+//	client.UsageTotal.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.UsageTotalUpsert) {
+//			SetCreatedAt(v+v).
+//		}).
+//		Exec(ctx)
+func (utcb *UsageTotalCreateBulk) OnConflict(opts ...sql.ConflictOption) *UsageTotalUpsertBulk {
+	utcb.conflict = opts
+	return &UsageTotalUpsertBulk{
+		create: utcb,
+	}
+}
+
+// OnConflictColumns calls `OnConflict` and configures the columns
+// as conflict target. Using this option is equivalent to using:
+//
+//	client.UsageTotal.Create().
+//		OnConflict(sql.ConflictColumns(columns...)).
+//		Exec(ctx)
+func (utcb *UsageTotalCreateBulk) OnConflictColumns(columns ...string) *UsageTotalUpsertBulk {
+	utcb.conflict = append(utcb.conflict, sql.ConflictColumns(columns...))
+	return &UsageTotalUpsertBulk{
+		create: utcb,
+	}
+}
+
+// UsageTotalUpsertBulk is the builder for "upsert"-ing
+// a bulk of UsageTotal nodes.
+type UsageTotalUpsertBulk struct {
+	create *UsageTotalCreateBulk
+}
+
+// UpdateNewValues updates the mutable fields using the new values that
+// were set on create. Using this option is equivalent to using:
+//
+//	client.UsageTotal.Create().
+//		OnConflict(
+//			sql.ResolveWithNewValues(),
+//			sql.ResolveWith(func(u *sql.UpdateSet) {
+//				u.SetIgnore(usagetotal.FieldID)
+//			}),
+//		).
+//		Exec(ctx)
+func (u *UsageTotalUpsertBulk) UpdateNewValues() *UsageTotalUpsertBulk {
+	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(usagetotal.FieldID)
+			}
+			if _, exists := b.mutation.CreatedAt(); exists {
+				s.SetIgnore(usagetotal.FieldCreatedAt)
+			}
+		}
+	}))
+	return u
+}
+
+// Ignore sets each column to itself in case of conflict.
+// Using this option is equivalent to using:
+//
+//	client.UsageTotal.Create().
+//		OnConflict(sql.ResolveWithIgnore()).
+//		Exec(ctx)
+func (u *UsageTotalUpsertBulk) Ignore() *UsageTotalUpsertBulk {
+	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 *UsageTotalUpsertBulk) DoNothing() *UsageTotalUpsertBulk {
+	u.create.conflict = append(u.create.conflict, sql.DoNothing())
+	return u
+}
+
+// Update allows overriding fields `UPDATE` values. See the UsageTotalCreateBulk.OnConflict
+// documentation for more info.
+func (u *UsageTotalUpsertBulk) Update(set func(*UsageTotalUpsert)) *UsageTotalUpsertBulk {
+	u.create.conflict = append(u.create.conflict, sql.ResolveWith(func(update *sql.UpdateSet) {
+		set(&UsageTotalUpsert{UpdateSet: update})
+	}))
+	return u
+}
+
+// SetUpdatedAt sets the "updated_at" field.
+func (u *UsageTotalUpsertBulk) SetUpdatedAt(v time.Time) *UsageTotalUpsertBulk {
+	return u.Update(func(s *UsageTotalUpsert) {
+		s.SetUpdatedAt(v)
+	})
+}
+
+// UpdateUpdatedAt sets the "updated_at" field to the value that was provided on create.
+func (u *UsageTotalUpsertBulk) UpdateUpdatedAt() *UsageTotalUpsertBulk {
+	return u.Update(func(s *UsageTotalUpsert) {
+		s.UpdateUpdatedAt()
+	})
+}
+
+// SetStatus sets the "status" field.
+func (u *UsageTotalUpsertBulk) SetStatus(v uint8) *UsageTotalUpsertBulk {
+	return u.Update(func(s *UsageTotalUpsert) {
+		s.SetStatus(v)
+	})
+}
+
+// AddStatus adds v to the "status" field.
+func (u *UsageTotalUpsertBulk) AddStatus(v uint8) *UsageTotalUpsertBulk {
+	return u.Update(func(s *UsageTotalUpsert) {
+		s.AddStatus(v)
+	})
+}
+
+// UpdateStatus sets the "status" field to the value that was provided on create.
+func (u *UsageTotalUpsertBulk) UpdateStatus() *UsageTotalUpsertBulk {
+	return u.Update(func(s *UsageTotalUpsert) {
+		s.UpdateStatus()
+	})
+}
+
+// ClearStatus clears the value of the "status" field.
+func (u *UsageTotalUpsertBulk) ClearStatus() *UsageTotalUpsertBulk {
+	return u.Update(func(s *UsageTotalUpsert) {
+		s.ClearStatus()
+	})
+}
+
+// SetType sets the "type" field.
+func (u *UsageTotalUpsertBulk) SetType(v int) *UsageTotalUpsertBulk {
+	return u.Update(func(s *UsageTotalUpsert) {
+		s.SetType(v)
+	})
+}
+
+// AddType adds v to the "type" field.
+func (u *UsageTotalUpsertBulk) AddType(v int) *UsageTotalUpsertBulk {
+	return u.Update(func(s *UsageTotalUpsert) {
+		s.AddType(v)
+	})
+}
+
+// UpdateType sets the "type" field to the value that was provided on create.
+func (u *UsageTotalUpsertBulk) UpdateType() *UsageTotalUpsertBulk {
+	return u.Update(func(s *UsageTotalUpsert) {
+		s.UpdateType()
+	})
+}
+
+// ClearType clears the value of the "type" field.
+func (u *UsageTotalUpsertBulk) ClearType() *UsageTotalUpsertBulk {
+	return u.Update(func(s *UsageTotalUpsert) {
+		s.ClearType()
+	})
+}
+
+// SetBotID sets the "bot_id" field.
+func (u *UsageTotalUpsertBulk) SetBotID(v string) *UsageTotalUpsertBulk {
+	return u.Update(func(s *UsageTotalUpsert) {
+		s.SetBotID(v)
+	})
+}
+
+// UpdateBotID sets the "bot_id" field to the value that was provided on create.
+func (u *UsageTotalUpsertBulk) UpdateBotID() *UsageTotalUpsertBulk {
+	return u.Update(func(s *UsageTotalUpsert) {
+		s.UpdateBotID()
+	})
+}
+
+// SetTotalTokens sets the "total_tokens" field.
+func (u *UsageTotalUpsertBulk) SetTotalTokens(v uint64) *UsageTotalUpsertBulk {
+	return u.Update(func(s *UsageTotalUpsert) {
+		s.SetTotalTokens(v)
+	})
+}
+
+// AddTotalTokens adds v to the "total_tokens" field.
+func (u *UsageTotalUpsertBulk) AddTotalTokens(v uint64) *UsageTotalUpsertBulk {
+	return u.Update(func(s *UsageTotalUpsert) {
+		s.AddTotalTokens(v)
+	})
+}
+
+// UpdateTotalTokens sets the "total_tokens" field to the value that was provided on create.
+func (u *UsageTotalUpsertBulk) UpdateTotalTokens() *UsageTotalUpsertBulk {
+	return u.Update(func(s *UsageTotalUpsert) {
+		s.UpdateTotalTokens()
+	})
+}
+
+// ClearTotalTokens clears the value of the "total_tokens" field.
+func (u *UsageTotalUpsertBulk) ClearTotalTokens() *UsageTotalUpsertBulk {
+	return u.Update(func(s *UsageTotalUpsert) {
+		s.ClearTotalTokens()
+	})
+}
+
+// SetStartIndex sets the "start_index" field.
+func (u *UsageTotalUpsertBulk) SetStartIndex(v uint64) *UsageTotalUpsertBulk {
+	return u.Update(func(s *UsageTotalUpsert) {
+		s.SetStartIndex(v)
+	})
+}
+
+// AddStartIndex adds v to the "start_index" field.
+func (u *UsageTotalUpsertBulk) AddStartIndex(v uint64) *UsageTotalUpsertBulk {
+	return u.Update(func(s *UsageTotalUpsert) {
+		s.AddStartIndex(v)
+	})
+}
+
+// UpdateStartIndex sets the "start_index" field to the value that was provided on create.
+func (u *UsageTotalUpsertBulk) UpdateStartIndex() *UsageTotalUpsertBulk {
+	return u.Update(func(s *UsageTotalUpsert) {
+		s.UpdateStartIndex()
+	})
+}
+
+// ClearStartIndex clears the value of the "start_index" field.
+func (u *UsageTotalUpsertBulk) ClearStartIndex() *UsageTotalUpsertBulk {
+	return u.Update(func(s *UsageTotalUpsert) {
+		s.ClearStartIndex()
+	})
+}
+
+// SetEndIndex sets the "end_index" field.
+func (u *UsageTotalUpsertBulk) SetEndIndex(v uint64) *UsageTotalUpsertBulk {
+	return u.Update(func(s *UsageTotalUpsert) {
+		s.SetEndIndex(v)
+	})
+}
+
+// AddEndIndex adds v to the "end_index" field.
+func (u *UsageTotalUpsertBulk) AddEndIndex(v uint64) *UsageTotalUpsertBulk {
+	return u.Update(func(s *UsageTotalUpsert) {
+		s.AddEndIndex(v)
+	})
+}
+
+// UpdateEndIndex sets the "end_index" field to the value that was provided on create.
+func (u *UsageTotalUpsertBulk) UpdateEndIndex() *UsageTotalUpsertBulk {
+	return u.Update(func(s *UsageTotalUpsert) {
+		s.UpdateEndIndex()
+	})
+}
+
+// ClearEndIndex clears the value of the "end_index" field.
+func (u *UsageTotalUpsertBulk) ClearEndIndex() *UsageTotalUpsertBulk {
+	return u.Update(func(s *UsageTotalUpsert) {
+		s.ClearEndIndex()
+	})
+}
+
+// SetOrganizationID sets the "organization_id" field.
+func (u *UsageTotalUpsertBulk) SetOrganizationID(v uint64) *UsageTotalUpsertBulk {
+	return u.Update(func(s *UsageTotalUpsert) {
+		s.SetOrganizationID(v)
+	})
+}
+
+// AddOrganizationID adds v to the "organization_id" field.
+func (u *UsageTotalUpsertBulk) AddOrganizationID(v uint64) *UsageTotalUpsertBulk {
+	return u.Update(func(s *UsageTotalUpsert) {
+		s.AddOrganizationID(v)
+	})
+}
+
+// UpdateOrganizationID sets the "organization_id" field to the value that was provided on create.
+func (u *UsageTotalUpsertBulk) UpdateOrganizationID() *UsageTotalUpsertBulk {
+	return u.Update(func(s *UsageTotalUpsert) {
+		s.UpdateOrganizationID()
+	})
+}
+
+// ClearOrganizationID clears the value of the "organization_id" field.
+func (u *UsageTotalUpsertBulk) ClearOrganizationID() *UsageTotalUpsertBulk {
+	return u.Update(func(s *UsageTotalUpsert) {
+		s.ClearOrganizationID()
+	})
+}
+
+// Exec executes the query.
+func (u *UsageTotalUpsertBulk) 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 UsageTotalCreateBulk instead", i)
+		}
+	}
+	if len(u.create.conflict) == 0 {
+		return errors.New("ent: missing options for UsageTotalCreateBulk.OnConflict")
+	}
+	return u.create.Exec(ctx)
+}
+
+// ExecX is like Exec, but panics if an error occurs.
+func (u *UsageTotalUpsertBulk) ExecX(ctx context.Context) {
+	if err := u.create.Exec(ctx); err != nil {
+		panic(err)
+	}
+}

+ 88 - 0
ent/usagetotal_delete.go

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

+ 526 - 0
ent/usagetotal_query.go

@@ -0,0 +1,526 @@
+// Code generated by ent, DO NOT EDIT.
+
+package ent
+
+import (
+	"context"
+	"fmt"
+	"math"
+	"wechat-api/ent/predicate"
+	"wechat-api/ent/usagetotal"
+
+	"entgo.io/ent/dialect/sql"
+	"entgo.io/ent/dialect/sql/sqlgraph"
+	"entgo.io/ent/schema/field"
+)
+
+// UsageTotalQuery is the builder for querying UsageTotal entities.
+type UsageTotalQuery struct {
+	config
+	ctx        *QueryContext
+	order      []usagetotal.OrderOption
+	inters     []Interceptor
+	predicates []predicate.UsageTotal
+	// intermediate query (i.e. traversal path).
+	sql  *sql.Selector
+	path func(context.Context) (*sql.Selector, error)
+}
+
+// Where adds a new predicate for the UsageTotalQuery builder.
+func (utq *UsageTotalQuery) Where(ps ...predicate.UsageTotal) *UsageTotalQuery {
+	utq.predicates = append(utq.predicates, ps...)
+	return utq
+}
+
+// Limit the number of records to be returned by this query.
+func (utq *UsageTotalQuery) Limit(limit int) *UsageTotalQuery {
+	utq.ctx.Limit = &limit
+	return utq
+}
+
+// Offset to start from.
+func (utq *UsageTotalQuery) Offset(offset int) *UsageTotalQuery {
+	utq.ctx.Offset = &offset
+	return utq
+}
+
+// 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 (utq *UsageTotalQuery) Unique(unique bool) *UsageTotalQuery {
+	utq.ctx.Unique = &unique
+	return utq
+}
+
+// Order specifies how the records should be ordered.
+func (utq *UsageTotalQuery) Order(o ...usagetotal.OrderOption) *UsageTotalQuery {
+	utq.order = append(utq.order, o...)
+	return utq
+}
+
+// First returns the first UsageTotal entity from the query.
+// Returns a *NotFoundError when no UsageTotal was found.
+func (utq *UsageTotalQuery) First(ctx context.Context) (*UsageTotal, error) {
+	nodes, err := utq.Limit(1).All(setContextOp(ctx, utq.ctx, "First"))
+	if err != nil {
+		return nil, err
+	}
+	if len(nodes) == 0 {
+		return nil, &NotFoundError{usagetotal.Label}
+	}
+	return nodes[0], nil
+}
+
+// FirstX is like First, but panics if an error occurs.
+func (utq *UsageTotalQuery) FirstX(ctx context.Context) *UsageTotal {
+	node, err := utq.First(ctx)
+	if err != nil && !IsNotFound(err) {
+		panic(err)
+	}
+	return node
+}
+
+// FirstID returns the first UsageTotal ID from the query.
+// Returns a *NotFoundError when no UsageTotal ID was found.
+func (utq *UsageTotalQuery) FirstID(ctx context.Context) (id uint64, err error) {
+	var ids []uint64
+	if ids, err = utq.Limit(1).IDs(setContextOp(ctx, utq.ctx, "FirstID")); err != nil {
+		return
+	}
+	if len(ids) == 0 {
+		err = &NotFoundError{usagetotal.Label}
+		return
+	}
+	return ids[0], nil
+}
+
+// FirstIDX is like FirstID, but panics if an error occurs.
+func (utq *UsageTotalQuery) FirstIDX(ctx context.Context) uint64 {
+	id, err := utq.FirstID(ctx)
+	if err != nil && !IsNotFound(err) {
+		panic(err)
+	}
+	return id
+}
+
+// Only returns a single UsageTotal entity found by the query, ensuring it only returns one.
+// Returns a *NotSingularError when more than one UsageTotal entity is found.
+// Returns a *NotFoundError when no UsageTotal entities are found.
+func (utq *UsageTotalQuery) Only(ctx context.Context) (*UsageTotal, error) {
+	nodes, err := utq.Limit(2).All(setContextOp(ctx, utq.ctx, "Only"))
+	if err != nil {
+		return nil, err
+	}
+	switch len(nodes) {
+	case 1:
+		return nodes[0], nil
+	case 0:
+		return nil, &NotFoundError{usagetotal.Label}
+	default:
+		return nil, &NotSingularError{usagetotal.Label}
+	}
+}
+
+// OnlyX is like Only, but panics if an error occurs.
+func (utq *UsageTotalQuery) OnlyX(ctx context.Context) *UsageTotal {
+	node, err := utq.Only(ctx)
+	if err != nil {
+		panic(err)
+	}
+	return node
+}
+
+// OnlyID is like Only, but returns the only UsageTotal ID in the query.
+// Returns a *NotSingularError when more than one UsageTotal ID is found.
+// Returns a *NotFoundError when no entities are found.
+func (utq *UsageTotalQuery) OnlyID(ctx context.Context) (id uint64, err error) {
+	var ids []uint64
+	if ids, err = utq.Limit(2).IDs(setContextOp(ctx, utq.ctx, "OnlyID")); err != nil {
+		return
+	}
+	switch len(ids) {
+	case 1:
+		id = ids[0]
+	case 0:
+		err = &NotFoundError{usagetotal.Label}
+	default:
+		err = &NotSingularError{usagetotal.Label}
+	}
+	return
+}
+
+// OnlyIDX is like OnlyID, but panics if an error occurs.
+func (utq *UsageTotalQuery) OnlyIDX(ctx context.Context) uint64 {
+	id, err := utq.OnlyID(ctx)
+	if err != nil {
+		panic(err)
+	}
+	return id
+}
+
+// All executes the query and returns a list of UsageTotals.
+func (utq *UsageTotalQuery) All(ctx context.Context) ([]*UsageTotal, error) {
+	ctx = setContextOp(ctx, utq.ctx, "All")
+	if err := utq.prepareQuery(ctx); err != nil {
+		return nil, err
+	}
+	qr := querierAll[[]*UsageTotal, *UsageTotalQuery]()
+	return withInterceptors[[]*UsageTotal](ctx, utq, qr, utq.inters)
+}
+
+// AllX is like All, but panics if an error occurs.
+func (utq *UsageTotalQuery) AllX(ctx context.Context) []*UsageTotal {
+	nodes, err := utq.All(ctx)
+	if err != nil {
+		panic(err)
+	}
+	return nodes
+}
+
+// IDs executes the query and returns a list of UsageTotal IDs.
+func (utq *UsageTotalQuery) IDs(ctx context.Context) (ids []uint64, err error) {
+	if utq.ctx.Unique == nil && utq.path != nil {
+		utq.Unique(true)
+	}
+	ctx = setContextOp(ctx, utq.ctx, "IDs")
+	if err = utq.Select(usagetotal.FieldID).Scan(ctx, &ids); err != nil {
+		return nil, err
+	}
+	return ids, nil
+}
+
+// IDsX is like IDs, but panics if an error occurs.
+func (utq *UsageTotalQuery) IDsX(ctx context.Context) []uint64 {
+	ids, err := utq.IDs(ctx)
+	if err != nil {
+		panic(err)
+	}
+	return ids
+}
+
+// Count returns the count of the given query.
+func (utq *UsageTotalQuery) Count(ctx context.Context) (int, error) {
+	ctx = setContextOp(ctx, utq.ctx, "Count")
+	if err := utq.prepareQuery(ctx); err != nil {
+		return 0, err
+	}
+	return withInterceptors[int](ctx, utq, querierCount[*UsageTotalQuery](), utq.inters)
+}
+
+// CountX is like Count, but panics if an error occurs.
+func (utq *UsageTotalQuery) CountX(ctx context.Context) int {
+	count, err := utq.Count(ctx)
+	if err != nil {
+		panic(err)
+	}
+	return count
+}
+
+// Exist returns true if the query has elements in the graph.
+func (utq *UsageTotalQuery) Exist(ctx context.Context) (bool, error) {
+	ctx = setContextOp(ctx, utq.ctx, "Exist")
+	switch _, err := utq.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 (utq *UsageTotalQuery) ExistX(ctx context.Context) bool {
+	exist, err := utq.Exist(ctx)
+	if err != nil {
+		panic(err)
+	}
+	return exist
+}
+
+// Clone returns a duplicate of the UsageTotalQuery builder, including all associated steps. It can be
+// used to prepare common query builders and use them differently after the clone is made.
+func (utq *UsageTotalQuery) Clone() *UsageTotalQuery {
+	if utq == nil {
+		return nil
+	}
+	return &UsageTotalQuery{
+		config:     utq.config,
+		ctx:        utq.ctx.Clone(),
+		order:      append([]usagetotal.OrderOption{}, utq.order...),
+		inters:     append([]Interceptor{}, utq.inters...),
+		predicates: append([]predicate.UsageTotal{}, utq.predicates...),
+		// clone intermediate query.
+		sql:  utq.sql.Clone(),
+		path: utq.path,
+	}
+}
+
+// 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 {
+//		CreatedAt time.Time `json:"created_at,omitempty"`
+//		Count int `json:"count,omitempty"`
+//	}
+//
+//	client.UsageTotal.Query().
+//		GroupBy(usagetotal.FieldCreatedAt).
+//		Aggregate(ent.Count()).
+//		Scan(ctx, &v)
+func (utq *UsageTotalQuery) GroupBy(field string, fields ...string) *UsageTotalGroupBy {
+	utq.ctx.Fields = append([]string{field}, fields...)
+	grbuild := &UsageTotalGroupBy{build: utq}
+	grbuild.flds = &utq.ctx.Fields
+	grbuild.label = usagetotal.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 {
+//		CreatedAt time.Time `json:"created_at,omitempty"`
+//	}
+//
+//	client.UsageTotal.Query().
+//		Select(usagetotal.FieldCreatedAt).
+//		Scan(ctx, &v)
+func (utq *UsageTotalQuery) Select(fields ...string) *UsageTotalSelect {
+	utq.ctx.Fields = append(utq.ctx.Fields, fields...)
+	sbuild := &UsageTotalSelect{UsageTotalQuery: utq}
+	sbuild.label = usagetotal.Label
+	sbuild.flds, sbuild.scan = &utq.ctx.Fields, sbuild.Scan
+	return sbuild
+}
+
+// Aggregate returns a UsageTotalSelect configured with the given aggregations.
+func (utq *UsageTotalQuery) Aggregate(fns ...AggregateFunc) *UsageTotalSelect {
+	return utq.Select().Aggregate(fns...)
+}
+
+func (utq *UsageTotalQuery) prepareQuery(ctx context.Context) error {
+	for _, inter := range utq.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, utq); err != nil {
+				return err
+			}
+		}
+	}
+	for _, f := range utq.ctx.Fields {
+		if !usagetotal.ValidColumn(f) {
+			return &ValidationError{Name: f, err: fmt.Errorf("ent: invalid field %q for query", f)}
+		}
+	}
+	if utq.path != nil {
+		prev, err := utq.path(ctx)
+		if err != nil {
+			return err
+		}
+		utq.sql = prev
+	}
+	return nil
+}
+
+func (utq *UsageTotalQuery) sqlAll(ctx context.Context, hooks ...queryHook) ([]*UsageTotal, error) {
+	var (
+		nodes = []*UsageTotal{}
+		_spec = utq.querySpec()
+	)
+	_spec.ScanValues = func(columns []string) ([]any, error) {
+		return (*UsageTotal).scanValues(nil, columns)
+	}
+	_spec.Assign = func(columns []string, values []any) error {
+		node := &UsageTotal{config: utq.config}
+		nodes = append(nodes, node)
+		return node.assignValues(columns, values)
+	}
+	for i := range hooks {
+		hooks[i](ctx, _spec)
+	}
+	if err := sqlgraph.QueryNodes(ctx, utq.driver, _spec); err != nil {
+		return nil, err
+	}
+	if len(nodes) == 0 {
+		return nodes, nil
+	}
+	return nodes, nil
+}
+
+func (utq *UsageTotalQuery) sqlCount(ctx context.Context) (int, error) {
+	_spec := utq.querySpec()
+	_spec.Node.Columns = utq.ctx.Fields
+	if len(utq.ctx.Fields) > 0 {
+		_spec.Unique = utq.ctx.Unique != nil && *utq.ctx.Unique
+	}
+	return sqlgraph.CountNodes(ctx, utq.driver, _spec)
+}
+
+func (utq *UsageTotalQuery) querySpec() *sqlgraph.QuerySpec {
+	_spec := sqlgraph.NewQuerySpec(usagetotal.Table, usagetotal.Columns, sqlgraph.NewFieldSpec(usagetotal.FieldID, field.TypeUint64))
+	_spec.From = utq.sql
+	if unique := utq.ctx.Unique; unique != nil {
+		_spec.Unique = *unique
+	} else if utq.path != nil {
+		_spec.Unique = true
+	}
+	if fields := utq.ctx.Fields; len(fields) > 0 {
+		_spec.Node.Columns = make([]string, 0, len(fields))
+		_spec.Node.Columns = append(_spec.Node.Columns, usagetotal.FieldID)
+		for i := range fields {
+			if fields[i] != usagetotal.FieldID {
+				_spec.Node.Columns = append(_spec.Node.Columns, fields[i])
+			}
+		}
+	}
+	if ps := utq.predicates; len(ps) > 0 {
+		_spec.Predicate = func(selector *sql.Selector) {
+			for i := range ps {
+				ps[i](selector)
+			}
+		}
+	}
+	if limit := utq.ctx.Limit; limit != nil {
+		_spec.Limit = *limit
+	}
+	if offset := utq.ctx.Offset; offset != nil {
+		_spec.Offset = *offset
+	}
+	if ps := utq.order; len(ps) > 0 {
+		_spec.Order = func(selector *sql.Selector) {
+			for i := range ps {
+				ps[i](selector)
+			}
+		}
+	}
+	return _spec
+}
+
+func (utq *UsageTotalQuery) sqlQuery(ctx context.Context) *sql.Selector {
+	builder := sql.Dialect(utq.driver.Dialect())
+	t1 := builder.Table(usagetotal.Table)
+	columns := utq.ctx.Fields
+	if len(columns) == 0 {
+		columns = usagetotal.Columns
+	}
+	selector := builder.Select(t1.Columns(columns...)...).From(t1)
+	if utq.sql != nil {
+		selector = utq.sql
+		selector.Select(selector.Columns(columns...)...)
+	}
+	if utq.ctx.Unique != nil && *utq.ctx.Unique {
+		selector.Distinct()
+	}
+	for _, p := range utq.predicates {
+		p(selector)
+	}
+	for _, p := range utq.order {
+		p(selector)
+	}
+	if offset := utq.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 := utq.ctx.Limit; limit != nil {
+		selector.Limit(*limit)
+	}
+	return selector
+}
+
+// UsageTotalGroupBy is the group-by builder for UsageTotal entities.
+type UsageTotalGroupBy struct {
+	selector
+	build *UsageTotalQuery
+}
+
+// Aggregate adds the given aggregation functions to the group-by query.
+func (utgb *UsageTotalGroupBy) Aggregate(fns ...AggregateFunc) *UsageTotalGroupBy {
+	utgb.fns = append(utgb.fns, fns...)
+	return utgb
+}
+
+// Scan applies the selector query and scans the result into the given value.
+func (utgb *UsageTotalGroupBy) Scan(ctx context.Context, v any) error {
+	ctx = setContextOp(ctx, utgb.build.ctx, "GroupBy")
+	if err := utgb.build.prepareQuery(ctx); err != nil {
+		return err
+	}
+	return scanWithInterceptors[*UsageTotalQuery, *UsageTotalGroupBy](ctx, utgb.build, utgb, utgb.build.inters, v)
+}
+
+func (utgb *UsageTotalGroupBy) sqlScan(ctx context.Context, root *UsageTotalQuery, v any) error {
+	selector := root.sqlQuery(ctx).Select()
+	aggregation := make([]string, 0, len(utgb.fns))
+	for _, fn := range utgb.fns {
+		aggregation = append(aggregation, fn(selector))
+	}
+	if len(selector.SelectedColumns()) == 0 {
+		columns := make([]string, 0, len(*utgb.flds)+len(utgb.fns))
+		for _, f := range *utgb.flds {
+			columns = append(columns, selector.C(f))
+		}
+		columns = append(columns, aggregation...)
+		selector.Select(columns...)
+	}
+	selector.GroupBy(selector.Columns(*utgb.flds...)...)
+	if err := selector.Err(); err != nil {
+		return err
+	}
+	rows := &sql.Rows{}
+	query, args := selector.Query()
+	if err := utgb.build.driver.Query(ctx, query, args, rows); err != nil {
+		return err
+	}
+	defer rows.Close()
+	return sql.ScanSlice(rows, v)
+}
+
+// UsageTotalSelect is the builder for selecting fields of UsageTotal entities.
+type UsageTotalSelect struct {
+	*UsageTotalQuery
+	selector
+}
+
+// Aggregate adds the given aggregation functions to the selector query.
+func (uts *UsageTotalSelect) Aggregate(fns ...AggregateFunc) *UsageTotalSelect {
+	uts.fns = append(uts.fns, fns...)
+	return uts
+}
+
+// Scan applies the selector query and scans the result into the given value.
+func (uts *UsageTotalSelect) Scan(ctx context.Context, v any) error {
+	ctx = setContextOp(ctx, uts.ctx, "Select")
+	if err := uts.prepareQuery(ctx); err != nil {
+		return err
+	}
+	return scanWithInterceptors[*UsageTotalQuery, *UsageTotalSelect](ctx, uts.UsageTotalQuery, uts, uts.inters, v)
+}
+
+func (uts *UsageTotalSelect) sqlScan(ctx context.Context, root *UsageTotalQuery, v any) error {
+	selector := root.sqlQuery(ctx)
+	aggregation := make([]string, 0, len(uts.fns))
+	for _, fn := range uts.fns {
+		aggregation = append(aggregation, fn(selector))
+	}
+	switch n := len(*uts.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 := uts.driver.Query(ctx, query, args, rows); err != nil {
+		return err
+	}
+	defer rows.Close()
+	return sql.ScanSlice(rows, v)
+}

+ 678 - 0
ent/usagetotal_update.go

@@ -0,0 +1,678 @@
+// Code generated by ent, DO NOT EDIT.
+
+package ent
+
+import (
+	"context"
+	"errors"
+	"fmt"
+	"time"
+	"wechat-api/ent/predicate"
+	"wechat-api/ent/usagetotal"
+
+	"entgo.io/ent/dialect/sql"
+	"entgo.io/ent/dialect/sql/sqlgraph"
+	"entgo.io/ent/schema/field"
+)
+
+// UsageTotalUpdate is the builder for updating UsageTotal entities.
+type UsageTotalUpdate struct {
+	config
+	hooks    []Hook
+	mutation *UsageTotalMutation
+}
+
+// Where appends a list predicates to the UsageTotalUpdate builder.
+func (utu *UsageTotalUpdate) Where(ps ...predicate.UsageTotal) *UsageTotalUpdate {
+	utu.mutation.Where(ps...)
+	return utu
+}
+
+// SetUpdatedAt sets the "updated_at" field.
+func (utu *UsageTotalUpdate) SetUpdatedAt(t time.Time) *UsageTotalUpdate {
+	utu.mutation.SetUpdatedAt(t)
+	return utu
+}
+
+// SetStatus sets the "status" field.
+func (utu *UsageTotalUpdate) SetStatus(u uint8) *UsageTotalUpdate {
+	utu.mutation.ResetStatus()
+	utu.mutation.SetStatus(u)
+	return utu
+}
+
+// SetNillableStatus sets the "status" field if the given value is not nil.
+func (utu *UsageTotalUpdate) SetNillableStatus(u *uint8) *UsageTotalUpdate {
+	if u != nil {
+		utu.SetStatus(*u)
+	}
+	return utu
+}
+
+// AddStatus adds u to the "status" field.
+func (utu *UsageTotalUpdate) AddStatus(u int8) *UsageTotalUpdate {
+	utu.mutation.AddStatus(u)
+	return utu
+}
+
+// ClearStatus clears the value of the "status" field.
+func (utu *UsageTotalUpdate) ClearStatus() *UsageTotalUpdate {
+	utu.mutation.ClearStatus()
+	return utu
+}
+
+// SetType sets the "type" field.
+func (utu *UsageTotalUpdate) SetType(i int) *UsageTotalUpdate {
+	utu.mutation.ResetType()
+	utu.mutation.SetType(i)
+	return utu
+}
+
+// SetNillableType sets the "type" field if the given value is not nil.
+func (utu *UsageTotalUpdate) SetNillableType(i *int) *UsageTotalUpdate {
+	if i != nil {
+		utu.SetType(*i)
+	}
+	return utu
+}
+
+// AddType adds i to the "type" field.
+func (utu *UsageTotalUpdate) AddType(i int) *UsageTotalUpdate {
+	utu.mutation.AddType(i)
+	return utu
+}
+
+// ClearType clears the value of the "type" field.
+func (utu *UsageTotalUpdate) ClearType() *UsageTotalUpdate {
+	utu.mutation.ClearType()
+	return utu
+}
+
+// SetBotID sets the "bot_id" field.
+func (utu *UsageTotalUpdate) SetBotID(s string) *UsageTotalUpdate {
+	utu.mutation.SetBotID(s)
+	return utu
+}
+
+// SetNillableBotID sets the "bot_id" field if the given value is not nil.
+func (utu *UsageTotalUpdate) SetNillableBotID(s *string) *UsageTotalUpdate {
+	if s != nil {
+		utu.SetBotID(*s)
+	}
+	return utu
+}
+
+// SetTotalTokens sets the "total_tokens" field.
+func (utu *UsageTotalUpdate) SetTotalTokens(u uint64) *UsageTotalUpdate {
+	utu.mutation.ResetTotalTokens()
+	utu.mutation.SetTotalTokens(u)
+	return utu
+}
+
+// SetNillableTotalTokens sets the "total_tokens" field if the given value is not nil.
+func (utu *UsageTotalUpdate) SetNillableTotalTokens(u *uint64) *UsageTotalUpdate {
+	if u != nil {
+		utu.SetTotalTokens(*u)
+	}
+	return utu
+}
+
+// AddTotalTokens adds u to the "total_tokens" field.
+func (utu *UsageTotalUpdate) AddTotalTokens(u int64) *UsageTotalUpdate {
+	utu.mutation.AddTotalTokens(u)
+	return utu
+}
+
+// ClearTotalTokens clears the value of the "total_tokens" field.
+func (utu *UsageTotalUpdate) ClearTotalTokens() *UsageTotalUpdate {
+	utu.mutation.ClearTotalTokens()
+	return utu
+}
+
+// SetStartIndex sets the "start_index" field.
+func (utu *UsageTotalUpdate) SetStartIndex(u uint64) *UsageTotalUpdate {
+	utu.mutation.ResetStartIndex()
+	utu.mutation.SetStartIndex(u)
+	return utu
+}
+
+// SetNillableStartIndex sets the "start_index" field if the given value is not nil.
+func (utu *UsageTotalUpdate) SetNillableStartIndex(u *uint64) *UsageTotalUpdate {
+	if u != nil {
+		utu.SetStartIndex(*u)
+	}
+	return utu
+}
+
+// AddStartIndex adds u to the "start_index" field.
+func (utu *UsageTotalUpdate) AddStartIndex(u int64) *UsageTotalUpdate {
+	utu.mutation.AddStartIndex(u)
+	return utu
+}
+
+// ClearStartIndex clears the value of the "start_index" field.
+func (utu *UsageTotalUpdate) ClearStartIndex() *UsageTotalUpdate {
+	utu.mutation.ClearStartIndex()
+	return utu
+}
+
+// SetEndIndex sets the "end_index" field.
+func (utu *UsageTotalUpdate) SetEndIndex(u uint64) *UsageTotalUpdate {
+	utu.mutation.ResetEndIndex()
+	utu.mutation.SetEndIndex(u)
+	return utu
+}
+
+// SetNillableEndIndex sets the "end_index" field if the given value is not nil.
+func (utu *UsageTotalUpdate) SetNillableEndIndex(u *uint64) *UsageTotalUpdate {
+	if u != nil {
+		utu.SetEndIndex(*u)
+	}
+	return utu
+}
+
+// AddEndIndex adds u to the "end_index" field.
+func (utu *UsageTotalUpdate) AddEndIndex(u int64) *UsageTotalUpdate {
+	utu.mutation.AddEndIndex(u)
+	return utu
+}
+
+// ClearEndIndex clears the value of the "end_index" field.
+func (utu *UsageTotalUpdate) ClearEndIndex() *UsageTotalUpdate {
+	utu.mutation.ClearEndIndex()
+	return utu
+}
+
+// SetOrganizationID sets the "organization_id" field.
+func (utu *UsageTotalUpdate) SetOrganizationID(u uint64) *UsageTotalUpdate {
+	utu.mutation.ResetOrganizationID()
+	utu.mutation.SetOrganizationID(u)
+	return utu
+}
+
+// SetNillableOrganizationID sets the "organization_id" field if the given value is not nil.
+func (utu *UsageTotalUpdate) SetNillableOrganizationID(u *uint64) *UsageTotalUpdate {
+	if u != nil {
+		utu.SetOrganizationID(*u)
+	}
+	return utu
+}
+
+// AddOrganizationID adds u to the "organization_id" field.
+func (utu *UsageTotalUpdate) AddOrganizationID(u int64) *UsageTotalUpdate {
+	utu.mutation.AddOrganizationID(u)
+	return utu
+}
+
+// ClearOrganizationID clears the value of the "organization_id" field.
+func (utu *UsageTotalUpdate) ClearOrganizationID() *UsageTotalUpdate {
+	utu.mutation.ClearOrganizationID()
+	return utu
+}
+
+// Mutation returns the UsageTotalMutation object of the builder.
+func (utu *UsageTotalUpdate) Mutation() *UsageTotalMutation {
+	return utu.mutation
+}
+
+// Save executes the query and returns the number of nodes affected by the update operation.
+func (utu *UsageTotalUpdate) Save(ctx context.Context) (int, error) {
+	utu.defaults()
+	return withHooks(ctx, utu.sqlSave, utu.mutation, utu.hooks)
+}
+
+// SaveX is like Save, but panics if an error occurs.
+func (utu *UsageTotalUpdate) SaveX(ctx context.Context) int {
+	affected, err := utu.Save(ctx)
+	if err != nil {
+		panic(err)
+	}
+	return affected
+}
+
+// Exec executes the query.
+func (utu *UsageTotalUpdate) Exec(ctx context.Context) error {
+	_, err := utu.Save(ctx)
+	return err
+}
+
+// ExecX is like Exec, but panics if an error occurs.
+func (utu *UsageTotalUpdate) ExecX(ctx context.Context) {
+	if err := utu.Exec(ctx); err != nil {
+		panic(err)
+	}
+}
+
+// defaults sets the default values of the builder before save.
+func (utu *UsageTotalUpdate) defaults() {
+	if _, ok := utu.mutation.UpdatedAt(); !ok {
+		v := usagetotal.UpdateDefaultUpdatedAt()
+		utu.mutation.SetUpdatedAt(v)
+	}
+}
+
+func (utu *UsageTotalUpdate) sqlSave(ctx context.Context) (n int, err error) {
+	_spec := sqlgraph.NewUpdateSpec(usagetotal.Table, usagetotal.Columns, sqlgraph.NewFieldSpec(usagetotal.FieldID, field.TypeUint64))
+	if ps := utu.mutation.predicates; len(ps) > 0 {
+		_spec.Predicate = func(selector *sql.Selector) {
+			for i := range ps {
+				ps[i](selector)
+			}
+		}
+	}
+	if value, ok := utu.mutation.UpdatedAt(); ok {
+		_spec.SetField(usagetotal.FieldUpdatedAt, field.TypeTime, value)
+	}
+	if value, ok := utu.mutation.Status(); ok {
+		_spec.SetField(usagetotal.FieldStatus, field.TypeUint8, value)
+	}
+	if value, ok := utu.mutation.AddedStatus(); ok {
+		_spec.AddField(usagetotal.FieldStatus, field.TypeUint8, value)
+	}
+	if utu.mutation.StatusCleared() {
+		_spec.ClearField(usagetotal.FieldStatus, field.TypeUint8)
+	}
+	if value, ok := utu.mutation.GetType(); ok {
+		_spec.SetField(usagetotal.FieldType, field.TypeInt, value)
+	}
+	if value, ok := utu.mutation.AddedType(); ok {
+		_spec.AddField(usagetotal.FieldType, field.TypeInt, value)
+	}
+	if utu.mutation.TypeCleared() {
+		_spec.ClearField(usagetotal.FieldType, field.TypeInt)
+	}
+	if value, ok := utu.mutation.BotID(); ok {
+		_spec.SetField(usagetotal.FieldBotID, field.TypeString, value)
+	}
+	if value, ok := utu.mutation.TotalTokens(); ok {
+		_spec.SetField(usagetotal.FieldTotalTokens, field.TypeUint64, value)
+	}
+	if value, ok := utu.mutation.AddedTotalTokens(); ok {
+		_spec.AddField(usagetotal.FieldTotalTokens, field.TypeUint64, value)
+	}
+	if utu.mutation.TotalTokensCleared() {
+		_spec.ClearField(usagetotal.FieldTotalTokens, field.TypeUint64)
+	}
+	if value, ok := utu.mutation.StartIndex(); ok {
+		_spec.SetField(usagetotal.FieldStartIndex, field.TypeUint64, value)
+	}
+	if value, ok := utu.mutation.AddedStartIndex(); ok {
+		_spec.AddField(usagetotal.FieldStartIndex, field.TypeUint64, value)
+	}
+	if utu.mutation.StartIndexCleared() {
+		_spec.ClearField(usagetotal.FieldStartIndex, field.TypeUint64)
+	}
+	if value, ok := utu.mutation.EndIndex(); ok {
+		_spec.SetField(usagetotal.FieldEndIndex, field.TypeUint64, value)
+	}
+	if value, ok := utu.mutation.AddedEndIndex(); ok {
+		_spec.AddField(usagetotal.FieldEndIndex, field.TypeUint64, value)
+	}
+	if utu.mutation.EndIndexCleared() {
+		_spec.ClearField(usagetotal.FieldEndIndex, field.TypeUint64)
+	}
+	if value, ok := utu.mutation.OrganizationID(); ok {
+		_spec.SetField(usagetotal.FieldOrganizationID, field.TypeUint64, value)
+	}
+	if value, ok := utu.mutation.AddedOrganizationID(); ok {
+		_spec.AddField(usagetotal.FieldOrganizationID, field.TypeUint64, value)
+	}
+	if utu.mutation.OrganizationIDCleared() {
+		_spec.ClearField(usagetotal.FieldOrganizationID, field.TypeUint64)
+	}
+	if n, err = sqlgraph.UpdateNodes(ctx, utu.driver, _spec); err != nil {
+		if _, ok := err.(*sqlgraph.NotFoundError); ok {
+			err = &NotFoundError{usagetotal.Label}
+		} else if sqlgraph.IsConstraintError(err) {
+			err = &ConstraintError{msg: err.Error(), wrap: err}
+		}
+		return 0, err
+	}
+	utu.mutation.done = true
+	return n, nil
+}
+
+// UsageTotalUpdateOne is the builder for updating a single UsageTotal entity.
+type UsageTotalUpdateOne struct {
+	config
+	fields   []string
+	hooks    []Hook
+	mutation *UsageTotalMutation
+}
+
+// SetUpdatedAt sets the "updated_at" field.
+func (utuo *UsageTotalUpdateOne) SetUpdatedAt(t time.Time) *UsageTotalUpdateOne {
+	utuo.mutation.SetUpdatedAt(t)
+	return utuo
+}
+
+// SetStatus sets the "status" field.
+func (utuo *UsageTotalUpdateOne) SetStatus(u uint8) *UsageTotalUpdateOne {
+	utuo.mutation.ResetStatus()
+	utuo.mutation.SetStatus(u)
+	return utuo
+}
+
+// SetNillableStatus sets the "status" field if the given value is not nil.
+func (utuo *UsageTotalUpdateOne) SetNillableStatus(u *uint8) *UsageTotalUpdateOne {
+	if u != nil {
+		utuo.SetStatus(*u)
+	}
+	return utuo
+}
+
+// AddStatus adds u to the "status" field.
+func (utuo *UsageTotalUpdateOne) AddStatus(u int8) *UsageTotalUpdateOne {
+	utuo.mutation.AddStatus(u)
+	return utuo
+}
+
+// ClearStatus clears the value of the "status" field.
+func (utuo *UsageTotalUpdateOne) ClearStatus() *UsageTotalUpdateOne {
+	utuo.mutation.ClearStatus()
+	return utuo
+}
+
+// SetType sets the "type" field.
+func (utuo *UsageTotalUpdateOne) SetType(i int) *UsageTotalUpdateOne {
+	utuo.mutation.ResetType()
+	utuo.mutation.SetType(i)
+	return utuo
+}
+
+// SetNillableType sets the "type" field if the given value is not nil.
+func (utuo *UsageTotalUpdateOne) SetNillableType(i *int) *UsageTotalUpdateOne {
+	if i != nil {
+		utuo.SetType(*i)
+	}
+	return utuo
+}
+
+// AddType adds i to the "type" field.
+func (utuo *UsageTotalUpdateOne) AddType(i int) *UsageTotalUpdateOne {
+	utuo.mutation.AddType(i)
+	return utuo
+}
+
+// ClearType clears the value of the "type" field.
+func (utuo *UsageTotalUpdateOne) ClearType() *UsageTotalUpdateOne {
+	utuo.mutation.ClearType()
+	return utuo
+}
+
+// SetBotID sets the "bot_id" field.
+func (utuo *UsageTotalUpdateOne) SetBotID(s string) *UsageTotalUpdateOne {
+	utuo.mutation.SetBotID(s)
+	return utuo
+}
+
+// SetNillableBotID sets the "bot_id" field if the given value is not nil.
+func (utuo *UsageTotalUpdateOne) SetNillableBotID(s *string) *UsageTotalUpdateOne {
+	if s != nil {
+		utuo.SetBotID(*s)
+	}
+	return utuo
+}
+
+// SetTotalTokens sets the "total_tokens" field.
+func (utuo *UsageTotalUpdateOne) SetTotalTokens(u uint64) *UsageTotalUpdateOne {
+	utuo.mutation.ResetTotalTokens()
+	utuo.mutation.SetTotalTokens(u)
+	return utuo
+}
+
+// SetNillableTotalTokens sets the "total_tokens" field if the given value is not nil.
+func (utuo *UsageTotalUpdateOne) SetNillableTotalTokens(u *uint64) *UsageTotalUpdateOne {
+	if u != nil {
+		utuo.SetTotalTokens(*u)
+	}
+	return utuo
+}
+
+// AddTotalTokens adds u to the "total_tokens" field.
+func (utuo *UsageTotalUpdateOne) AddTotalTokens(u int64) *UsageTotalUpdateOne {
+	utuo.mutation.AddTotalTokens(u)
+	return utuo
+}
+
+// ClearTotalTokens clears the value of the "total_tokens" field.
+func (utuo *UsageTotalUpdateOne) ClearTotalTokens() *UsageTotalUpdateOne {
+	utuo.mutation.ClearTotalTokens()
+	return utuo
+}
+
+// SetStartIndex sets the "start_index" field.
+func (utuo *UsageTotalUpdateOne) SetStartIndex(u uint64) *UsageTotalUpdateOne {
+	utuo.mutation.ResetStartIndex()
+	utuo.mutation.SetStartIndex(u)
+	return utuo
+}
+
+// SetNillableStartIndex sets the "start_index" field if the given value is not nil.
+func (utuo *UsageTotalUpdateOne) SetNillableStartIndex(u *uint64) *UsageTotalUpdateOne {
+	if u != nil {
+		utuo.SetStartIndex(*u)
+	}
+	return utuo
+}
+
+// AddStartIndex adds u to the "start_index" field.
+func (utuo *UsageTotalUpdateOne) AddStartIndex(u int64) *UsageTotalUpdateOne {
+	utuo.mutation.AddStartIndex(u)
+	return utuo
+}
+
+// ClearStartIndex clears the value of the "start_index" field.
+func (utuo *UsageTotalUpdateOne) ClearStartIndex() *UsageTotalUpdateOne {
+	utuo.mutation.ClearStartIndex()
+	return utuo
+}
+
+// SetEndIndex sets the "end_index" field.
+func (utuo *UsageTotalUpdateOne) SetEndIndex(u uint64) *UsageTotalUpdateOne {
+	utuo.mutation.ResetEndIndex()
+	utuo.mutation.SetEndIndex(u)
+	return utuo
+}
+
+// SetNillableEndIndex sets the "end_index" field if the given value is not nil.
+func (utuo *UsageTotalUpdateOne) SetNillableEndIndex(u *uint64) *UsageTotalUpdateOne {
+	if u != nil {
+		utuo.SetEndIndex(*u)
+	}
+	return utuo
+}
+
+// AddEndIndex adds u to the "end_index" field.
+func (utuo *UsageTotalUpdateOne) AddEndIndex(u int64) *UsageTotalUpdateOne {
+	utuo.mutation.AddEndIndex(u)
+	return utuo
+}
+
+// ClearEndIndex clears the value of the "end_index" field.
+func (utuo *UsageTotalUpdateOne) ClearEndIndex() *UsageTotalUpdateOne {
+	utuo.mutation.ClearEndIndex()
+	return utuo
+}
+
+// SetOrganizationID sets the "organization_id" field.
+func (utuo *UsageTotalUpdateOne) SetOrganizationID(u uint64) *UsageTotalUpdateOne {
+	utuo.mutation.ResetOrganizationID()
+	utuo.mutation.SetOrganizationID(u)
+	return utuo
+}
+
+// SetNillableOrganizationID sets the "organization_id" field if the given value is not nil.
+func (utuo *UsageTotalUpdateOne) SetNillableOrganizationID(u *uint64) *UsageTotalUpdateOne {
+	if u != nil {
+		utuo.SetOrganizationID(*u)
+	}
+	return utuo
+}
+
+// AddOrganizationID adds u to the "organization_id" field.
+func (utuo *UsageTotalUpdateOne) AddOrganizationID(u int64) *UsageTotalUpdateOne {
+	utuo.mutation.AddOrganizationID(u)
+	return utuo
+}
+
+// ClearOrganizationID clears the value of the "organization_id" field.
+func (utuo *UsageTotalUpdateOne) ClearOrganizationID() *UsageTotalUpdateOne {
+	utuo.mutation.ClearOrganizationID()
+	return utuo
+}
+
+// Mutation returns the UsageTotalMutation object of the builder.
+func (utuo *UsageTotalUpdateOne) Mutation() *UsageTotalMutation {
+	return utuo.mutation
+}
+
+// Where appends a list predicates to the UsageTotalUpdate builder.
+func (utuo *UsageTotalUpdateOne) Where(ps ...predicate.UsageTotal) *UsageTotalUpdateOne {
+	utuo.mutation.Where(ps...)
+	return utuo
+}
+
+// Select allows selecting one or more fields (columns) of the returned entity.
+// The default is selecting all fields defined in the entity schema.
+func (utuo *UsageTotalUpdateOne) Select(field string, fields ...string) *UsageTotalUpdateOne {
+	utuo.fields = append([]string{field}, fields...)
+	return utuo
+}
+
+// Save executes the query and returns the updated UsageTotal entity.
+func (utuo *UsageTotalUpdateOne) Save(ctx context.Context) (*UsageTotal, error) {
+	utuo.defaults()
+	return withHooks(ctx, utuo.sqlSave, utuo.mutation, utuo.hooks)
+}
+
+// SaveX is like Save, but panics if an error occurs.
+func (utuo *UsageTotalUpdateOne) SaveX(ctx context.Context) *UsageTotal {
+	node, err := utuo.Save(ctx)
+	if err != nil {
+		panic(err)
+	}
+	return node
+}
+
+// Exec executes the query on the entity.
+func (utuo *UsageTotalUpdateOne) Exec(ctx context.Context) error {
+	_, err := utuo.Save(ctx)
+	return err
+}
+
+// ExecX is like Exec, but panics if an error occurs.
+func (utuo *UsageTotalUpdateOne) ExecX(ctx context.Context) {
+	if err := utuo.Exec(ctx); err != nil {
+		panic(err)
+	}
+}
+
+// defaults sets the default values of the builder before save.
+func (utuo *UsageTotalUpdateOne) defaults() {
+	if _, ok := utuo.mutation.UpdatedAt(); !ok {
+		v := usagetotal.UpdateDefaultUpdatedAt()
+		utuo.mutation.SetUpdatedAt(v)
+	}
+}
+
+func (utuo *UsageTotalUpdateOne) sqlSave(ctx context.Context) (_node *UsageTotal, err error) {
+	_spec := sqlgraph.NewUpdateSpec(usagetotal.Table, usagetotal.Columns, sqlgraph.NewFieldSpec(usagetotal.FieldID, field.TypeUint64))
+	id, ok := utuo.mutation.ID()
+	if !ok {
+		return nil, &ValidationError{Name: "id", err: errors.New(`ent: missing "UsageTotal.id" for update`)}
+	}
+	_spec.Node.ID.Value = id
+	if fields := utuo.fields; len(fields) > 0 {
+		_spec.Node.Columns = make([]string, 0, len(fields))
+		_spec.Node.Columns = append(_spec.Node.Columns, usagetotal.FieldID)
+		for _, f := range fields {
+			if !usagetotal.ValidColumn(f) {
+				return nil, &ValidationError{Name: f, err: fmt.Errorf("ent: invalid field %q for query", f)}
+			}
+			if f != usagetotal.FieldID {
+				_spec.Node.Columns = append(_spec.Node.Columns, f)
+			}
+		}
+	}
+	if ps := utuo.mutation.predicates; len(ps) > 0 {
+		_spec.Predicate = func(selector *sql.Selector) {
+			for i := range ps {
+				ps[i](selector)
+			}
+		}
+	}
+	if value, ok := utuo.mutation.UpdatedAt(); ok {
+		_spec.SetField(usagetotal.FieldUpdatedAt, field.TypeTime, value)
+	}
+	if value, ok := utuo.mutation.Status(); ok {
+		_spec.SetField(usagetotal.FieldStatus, field.TypeUint8, value)
+	}
+	if value, ok := utuo.mutation.AddedStatus(); ok {
+		_spec.AddField(usagetotal.FieldStatus, field.TypeUint8, value)
+	}
+	if utuo.mutation.StatusCleared() {
+		_spec.ClearField(usagetotal.FieldStatus, field.TypeUint8)
+	}
+	if value, ok := utuo.mutation.GetType(); ok {
+		_spec.SetField(usagetotal.FieldType, field.TypeInt, value)
+	}
+	if value, ok := utuo.mutation.AddedType(); ok {
+		_spec.AddField(usagetotal.FieldType, field.TypeInt, value)
+	}
+	if utuo.mutation.TypeCleared() {
+		_spec.ClearField(usagetotal.FieldType, field.TypeInt)
+	}
+	if value, ok := utuo.mutation.BotID(); ok {
+		_spec.SetField(usagetotal.FieldBotID, field.TypeString, value)
+	}
+	if value, ok := utuo.mutation.TotalTokens(); ok {
+		_spec.SetField(usagetotal.FieldTotalTokens, field.TypeUint64, value)
+	}
+	if value, ok := utuo.mutation.AddedTotalTokens(); ok {
+		_spec.AddField(usagetotal.FieldTotalTokens, field.TypeUint64, value)
+	}
+	if utuo.mutation.TotalTokensCleared() {
+		_spec.ClearField(usagetotal.FieldTotalTokens, field.TypeUint64)
+	}
+	if value, ok := utuo.mutation.StartIndex(); ok {
+		_spec.SetField(usagetotal.FieldStartIndex, field.TypeUint64, value)
+	}
+	if value, ok := utuo.mutation.AddedStartIndex(); ok {
+		_spec.AddField(usagetotal.FieldStartIndex, field.TypeUint64, value)
+	}
+	if utuo.mutation.StartIndexCleared() {
+		_spec.ClearField(usagetotal.FieldStartIndex, field.TypeUint64)
+	}
+	if value, ok := utuo.mutation.EndIndex(); ok {
+		_spec.SetField(usagetotal.FieldEndIndex, field.TypeUint64, value)
+	}
+	if value, ok := utuo.mutation.AddedEndIndex(); ok {
+		_spec.AddField(usagetotal.FieldEndIndex, field.TypeUint64, value)
+	}
+	if utuo.mutation.EndIndexCleared() {
+		_spec.ClearField(usagetotal.FieldEndIndex, field.TypeUint64)
+	}
+	if value, ok := utuo.mutation.OrganizationID(); ok {
+		_spec.SetField(usagetotal.FieldOrganizationID, field.TypeUint64, value)
+	}
+	if value, ok := utuo.mutation.AddedOrganizationID(); ok {
+		_spec.AddField(usagetotal.FieldOrganizationID, field.TypeUint64, value)
+	}
+	if utuo.mutation.OrganizationIDCleared() {
+		_spec.ClearField(usagetotal.FieldOrganizationID, field.TypeUint64)
+	}
+	_node = &UsageTotal{config: utuo.config}
+	_spec.Assign = _node.assignValues
+	_spec.ScanValues = _node.scanValues
+	if err = sqlgraph.UpdateNode(ctx, utuo.driver, _spec); err != nil {
+		if _, ok := err.(*sqlgraph.NotFoundError); ok {
+			err = &NotFoundError{usagetotal.Label}
+		} else if sqlgraph.IsConstraintError(err) {
+			err = &ConstraintError{msg: err.Error(), wrap: err}
+		}
+		return nil, err
+	}
+	utuo.mutation.done = true
+	return _node, nil
+}

+ 35 - 0
hook/contact.go

@@ -1,7 +1,9 @@
 package hook
 
 import (
+	"encoding/json"
 	"fmt"
+	"github.com/gorilla/websocket"
 	"strings"
 )
 
@@ -69,3 +71,36 @@ func (h *Hook) AddNewFriend(v3_wxid string, v4 string, desc string, addType stri
 	}
 	return
 }
+
+func (h *Hook) RequestChatRoomInfo(ChatRoomId, wxWxid string) error {
+	conn, err := h.connWorkPhone()
+	if err != nil {
+		err = fmt.Errorf("RequestChatRoomInfo failed")
+		return err
+	}
+	defer func(conn *websocket.Conn) {
+		err = conn.Close()
+		if err != nil {
+			err = fmt.Errorf("RequestChatRoomInfo failed")
+		}
+	}(conn)
+
+	message := map[string]interface{}{
+		"MsgType": "RequestChatRoomInfoTask",
+		"Content": map[string]interface{}{
+			"WeChatId":   wxWxid,
+			"ChatRoomId": ChatRoomId,
+		},
+	}
+	transportMessageJSON, err := json.Marshal(message)
+	if err != nil {
+		return err
+	}
+	// 发送 JSON 消息
+	err = conn.WriteMessage(websocket.TextMessage, transportMessageJSON)
+	if err != nil {
+		return fmt.Errorf("failed to send message: %v", err)
+	}
+
+	return nil
+}

+ 44 - 0
internal/handler/UsageDetail/get_usage_detail_list_handler.go

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

+ 44 - 0
internal/handler/UsageTotal/get_usage_total_list_handler.go

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

+ 30 - 0
internal/handler/routes.go

@@ -7,6 +7,8 @@ import (
 	ChatRoomMember "wechat-api/internal/handler/ChatRoomMember"
 	Message "wechat-api/internal/handler/Message"
 	Msg "wechat-api/internal/handler/Msg"
+	UsageDetail "wechat-api/internal/handler/UsageDetail"
+	UsageTotal "wechat-api/internal/handler/UsageTotal"
 	User "wechat-api/internal/handler/User"
 	WechatServer "wechat-api/internal/handler/WechatServer"
 	WorkPhone "wechat-api/internal/handler/WorkPhone"
@@ -1431,4 +1433,32 @@ 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:    "/usage_detail/list",
+					Handler: UsageDetail.GetUsageDetailListHandler(serverCtx),
+				},
+			}...,
+		),
+		rest.WithJwt(serverCtx.Config.Auth.AccessSecret),
+	)
+
+	server.AddRoutes(
+		rest.WithMiddlewares(
+			[]rest.Middleware{serverCtx.Authority},
+			[]rest.Route{
+				{
+					Method:  http.MethodPost,
+					Path:    "/usage_total/list",
+					Handler: UsageTotal.GetUsageTotalListHandler(serverCtx),
+				},
+			}...,
+		),
+		rest.WithJwt(serverCtx.Config.Auth.AccessSecret),
+	)
 }

+ 74 - 0
internal/logic/UsageDetail/get_usage_detail_list_logic.go

@@ -0,0 +1,74 @@
+package UsageDetail
+
+import (
+	"context"
+	"github.com/suyuan32/simple-admin-common/msg/errormsg"
+	"github.com/suyuan32/simple-admin-common/utils/pointy"
+	"wechat-api/ent/predicate"
+	"wechat-api/ent/usagedetail"
+	"wechat-api/internal/svc"
+	"wechat-api/internal/types"
+	"wechat-api/internal/utils/dberrorhandler"
+
+	"github.com/zeromicro/go-zero/core/logx"
+)
+
+type GetUsageDetailListLogic struct {
+	logx.Logger
+	ctx    context.Context
+	svcCtx *svc.ServiceContext
+}
+
+func NewGetUsageDetailListLogic(ctx context.Context, svcCtx *svc.ServiceContext) *GetUsageDetailListLogic {
+	return &GetUsageDetailListLogic{
+		Logger: logx.WithContext(ctx),
+		ctx:    ctx,
+		svcCtx: svcCtx}
+}
+
+func (l *GetUsageDetailListLogic) GetUsageDetailList(req *types.UsageDetailListReq) (resp *types.UsageDetailListResp, err error) {
+	organizationId := l.ctx.Value("organizationId").(uint64)
+	isAdmin := l.ctx.Value("isAdmin").(bool)
+
+	var predicates []predicate.UsageDetail
+
+	if !isAdmin {
+		predicates = append(predicates, usagedetail.OrganizationIDEQ(organizationId))
+	}
+	predicates = append(predicates, usagedetail.BotID(*req.BotId))
+
+	data, err := l.svcCtx.DB.UsageDetail.Query().Where(predicates...).Page(l.ctx, req.Page, req.PageSize)
+
+	if err != nil {
+		return nil, dberrorhandler.DefaultEntError(l.Logger, err, req)
+	}
+
+	resp = &types.UsageDetailListResp{}
+	resp.Msg = errormsg.Success
+	resp.Data.Total = data.PageDetails.Total
+
+	for _, v := range data.List {
+		resp.Data.Data = append(resp.Data.Data,
+			types.UsageDetailInfo{
+				BaseIDInfo: types.BaseIDInfo{
+					Id:        &v.ID,
+					CreatedAt: pointy.GetPointer(v.CreatedAt.UnixMilli()),
+					UpdatedAt: pointy.GetPointer(v.UpdatedAt.UnixMilli()),
+				},
+				Status:           &v.Status,
+				Type:             &v.Type,
+				BotId:            &v.BotID,
+				App:              &v.App,
+				SessionId:        &v.SessionID,
+				Request:          &v.Request,
+				Response:         &v.Response,
+				TotalTokens:      &v.TotalTokens,
+				PromptTokens:     &v.PromptTokens,
+				CompletionTokens: &v.CompletionTokens,
+				OrganizationId:   &v.OrganizationID,
+			})
+	}
+
+	return resp, nil
+	//return nil, nil
+}

+ 69 - 0
internal/logic/UsageTotal/get_usage_total_list_logic.go

@@ -0,0 +1,69 @@
+package UsageTotal
+
+import (
+	"context"
+	"fmt"
+	"github.com/suyuan32/simple-admin-common/msg/errormsg"
+	"github.com/suyuan32/simple-admin-common/utils/pointy"
+	"wechat-api/ent/predicate"
+	"wechat-api/ent/usagetotal"
+	"wechat-api/internal/svc"
+	"wechat-api/internal/types"
+	"wechat-api/internal/utils/dberrorhandler"
+
+	"github.com/zeromicro/go-zero/core/logx"
+)
+
+type GetUsageTotalListLogic struct {
+	logx.Logger
+	ctx    context.Context
+	svcCtx *svc.ServiceContext
+}
+
+func NewGetUsageTotalListLogic(ctx context.Context, svcCtx *svc.ServiceContext) *GetUsageTotalListLogic {
+	return &GetUsageTotalListLogic{
+		Logger: logx.WithContext(ctx),
+		ctx:    ctx,
+		svcCtx: svcCtx}
+}
+
+func (l *GetUsageTotalListLogic) GetUsageTotalList(req *types.UsageTotalListReq) (resp *types.UsageTotalListResp, err error) {
+	isAdmin := l.ctx.Value("isAdmin").(bool)
+
+	if !isAdmin {
+		return nil, fmt.Errorf("GetUsageTotalList failed")
+	}
+	var predicates []predicate.UsageTotal
+	predicates = append(predicates, usagetotal.OrganizationIDEQ(*req.OrganizationId))
+
+	data, err := l.svcCtx.DB.UsageTotal.Query().Where(predicates...).Page(l.ctx, req.Page, req.PageSize)
+
+	if err != nil {
+		return nil, dberrorhandler.DefaultEntError(l.Logger, err, req)
+	}
+
+	resp = &types.UsageTotalListResp{}
+	resp.Msg = errormsg.Success
+	resp.Data.Total = data.PageDetails.Total
+
+	for _, v := range data.List {
+		resp.Data.Data = append(resp.Data.Data,
+			types.UsageTotalInfo{
+				BaseIDInfo: types.BaseIDInfo{
+					Id:        &v.ID,
+					CreatedAt: pointy.GetPointer(v.CreatedAt.UnixMilli()),
+					UpdatedAt: pointy.GetPointer(v.UpdatedAt.UnixMilli()),
+				},
+				Status:         &v.Status,
+				Type:           &v.Type,
+				BotId:          &v.BotID,
+				TotalTokens:    &v.TotalTokens,
+				StartIndex:     &v.StartIndex,
+				EndIndex:       &v.EndIndex,
+				OrganizationId: &v.OrganizationID,
+			})
+	}
+
+	return resp, nil
+	//return nil, nil
+}

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

@@ -7,6 +7,7 @@ import (
 	"github.com/suyuan32/simple-admin-core/rpc/types/core"
 	"wechat-api/ent"
 	"wechat-api/ent/predicate"
+	"wechat-api/ent/usagetotal"
 	"wechat-api/ent/wx"
 	"wechat-api/hook"
 	"wechat-api/internal/svc"
@@ -179,6 +180,16 @@ func (l *GetWxListLogic) GetWxList(req *types.WxListReq) (*types.WxListResp, err
 			}
 		}
 
+		totalTokens := uint64(0)
+		usageTotalInfo, _ := l.svcCtx.DB.UsageTotal.Query().
+			Where(
+				usagetotal.BotID(wxid),
+			).
+			Only(l.ctx)
+		if usageTotalInfo != nil {
+			totalTokens = usageTotalInfo.TotalTokens
+		}
+
 		var agent types.AgentInfo
 		if v.Edges.Agent != nil {
 			agent = types.AgentInfo{
@@ -218,6 +229,7 @@ func (l *GetWxListLogic) GetWxList(req *types.WxListReq) (*types.WxListResp, err
 				AgentInfo:        &agent,
 				ApiBase:          &v.APIBase,
 				ApiKey:           &v.APIKey,
+				TotalTokens:      &totalTokens,
 			})
 	}
 

+ 2 - 0
internal/logic/Wxhook/get_friends_and_groups_logic.go

@@ -199,6 +199,7 @@ func (l *GetFriendsAndGroupsLogic) GetFriendsAndGroups(req *types.IDReq) (resp *
 		}
 	} else {
 		// 工作手机版本
+		hookClient := hook.NewHook("", "", "")
 		var result GetWechatFriendListResp
 		res, err := reqv3.C().DevMode().R().SetSuccessResult(&result).Post("http://chat.gkscrm.com:13086/pc/GetWechatFriendList?cid=" + wxInfo.ProcessID + "&wechatid=" + wxInfo.Wxid)
 		if err != nil {
@@ -213,6 +214,7 @@ func (l *GetFriendsAndGroupsLogic) GetFriendsAndGroups(req *types.IDReq) (resp *
 			friendType := 1
 			if friend.Type == 1 {
 				friendType = 2
+				_ = hookClient.RequestChatRoomInfo(friend.Friendid, wxInfo.Wxid)
 			} else {
 				friendType = 1
 			}

+ 100 - 0
internal/types/types.go

@@ -338,6 +338,8 @@ type WxInfo struct {
 	BlockList []ContactInfo `json:"blockList,optional"`
 	// 群黑名单
 	GroupBlockList []ContactInfo `json:"groupBlockList,optional"`
+	// 使用token总数
+	TotalTokens *uint64 `json:"totalTokens,optional"`
 }
 
 // swagger:model UpdateBlockAndAllowListReq
@@ -2750,3 +2752,101 @@ type AliyunAvatarInfoResp struct {
 	// AliyunAvatar information | AliyunAvatar数据
 	Data AliyunAvatarInfo `json:"data"`
 }
+
+// The response data of UsageDetail information | UsageDetail信息
+// swagger:model UsageDetailInfo
+type UsageDetailInfo struct {
+	BaseIDInfo
+	// Status 1: normal 2: ban | 状态 1 正常 2 禁用
+	Status *uint8 `json:"status,optional"`
+	// 1 微信 2 名片
+	Type *int
+	// 微信id
+	BotId *string `json:"botId,optional"`
+	// 微信id或open_id
+	ReceiverId *string `json:"receiverId,optional"`
+	// 1 cow-basic 2 cow-agent 3 cow-sop 4 mp-card 5 mp-employee
+	App *int
+	// 名片会话id
+	SessionId *uint64 `json:"sessionId,optional"`
+	// 请求内容
+	Request *string `json:"request,optional"`
+	// 响应内容
+	Response *string `json:"response,optional"`
+	// 使用token总数
+	TotalTokens *uint64 `json:"totalTokens,optional"`
+	// 请求token数
+	PromptTokens *uint64 `json:"promptTokens,optional"`
+	// 响应token数
+	CompletionTokens *uint64 `json:"completionTokens,optional"`
+	// 组织ID
+	OrganizationId *uint64 `json:"organizationId,optional"`
+}
+
+// The response data of UsageDetail list | UsageDetail列表数据
+// swagger:model UsageDetailListResp
+type UsageDetailListResp struct {
+	BaseDataInfo
+	// UsageDetail list data | UsageDetail列表数据
+	Data UsageDetailListInfo `json:"data"`
+}
+
+// UsageDetail list data | UsageDetail列表数据
+// swagger:model UsageDetailListInfo
+type UsageDetailListInfo struct {
+	BaseListInfo
+	// The API list data | UsageDetail列表数据
+	Data []UsageDetailInfo `json:"data"`
+}
+
+// Get wx list request params | Wx列表请求参数
+// swagger:model UsageDetailListReq
+type UsageDetailListReq struct {
+	PageInfo
+	// 租户id
+	BotId *string `json:"botId,optional"`
+}
+
+// The response data of UsageTotal information | UsageTotal信息
+// swagger:model UsageTotalInfo
+type UsageTotalInfo struct {
+	BaseIDInfo
+	// Status 1: normal 2: ban | 状态 1 正常 2 禁用
+	Status *uint8 `json:"status,optional"`
+	// 1 微信 2 名片
+	Type *int
+	// 微信或名片id
+	BotId *string `json:"botId,optional"`
+	// 使用token总数
+	TotalTokens *uint64 `json:"totalTokens,optional"`
+	// 重制后的起始usage_detail 索引
+	StartIndex *uint64 `json:"startIndex,optional"`
+	// usage_detail 索引
+	EndIndex *uint64 `json:"endIndex,optional"`
+	// 组织ID
+	OrganizationId *uint64 `json:"organizationId,optional"`
+}
+
+// The response data of UsageTotal list | UsageTotal列表数据
+// swagger:model UsageTotalListResp
+type UsageTotalListResp struct {
+	BaseDataInfo
+	// UsageTotal list data | UsageTotal列表数据
+	Data UsageTotalListInfo `json:"data"`
+}
+
+// UsageTotal list data | UsageTotal列表数据
+// swagger:model UsageTotalListInfo
+type UsageTotalListInfo struct {
+	BaseListInfo
+	// The API list data | UsageTotal列表数据
+	Data []UsageTotalInfo `json:"data"`
+}
+
+// Get wx list request params | Wx列表请求参数
+// swagger:model UsageTotalListReq
+type UsageTotalListReq struct {
+	PageInfo
+	// 租户id
+	OrganizationId *uint64 `json:"organizationId,optional"`
+}