Browse Source

接口的异步任务受理(包括相关ent及logic内的处理)

liwei 1 month ago
parent
commit
ffb53b6c03

+ 161 - 18
ent/client.go

@@ -20,6 +20,7 @@ import (
 	"wechat-api/ent/category"
 	"wechat-api/ent/chatrecords"
 	"wechat-api/ent/chatsession"
+	"wechat-api/ent/compapijob"
 	"wechat-api/ent/contact"
 	"wechat-api/ent/creditbalance"
 	"wechat-api/ent/creditusage"
@@ -84,6 +85,8 @@ type Client struct {
 	ChatRecords *ChatRecordsClient
 	// ChatSession is the client for interacting with the ChatSession builders.
 	ChatSession *ChatSessionClient
+	// CompapiJob is the client for interacting with the CompapiJob builders.
+	CompapiJob *CompapiJobClient
 	// Contact is the client for interacting with the Contact builders.
 	Contact *ContactClient
 	// CreditBalance is the client for interacting with the CreditBalance builders.
@@ -168,6 +171,7 @@ func (c *Client) init() {
 	c.Category = NewCategoryClient(c.config)
 	c.ChatRecords = NewChatRecordsClient(c.config)
 	c.ChatSession = NewChatSessionClient(c.config)
+	c.CompapiJob = NewCompapiJobClient(c.config)
 	c.Contact = NewContactClient(c.config)
 	c.CreditBalance = NewCreditBalanceClient(c.config)
 	c.CreditUsage = NewCreditUsageClient(c.config)
@@ -301,6 +305,7 @@ func (c *Client) Tx(ctx context.Context) (*Tx, error) {
 		Category:            NewCategoryClient(cfg),
 		ChatRecords:         NewChatRecordsClient(cfg),
 		ChatSession:         NewChatSessionClient(cfg),
+		CompapiJob:          NewCompapiJobClient(cfg),
 		Contact:             NewContactClient(cfg),
 		CreditBalance:       NewCreditBalanceClient(cfg),
 		CreditUsage:         NewCreditUsageClient(cfg),
@@ -361,6 +366,7 @@ func (c *Client) BeginTx(ctx context.Context, opts *sql.TxOptions) (*Tx, error)
 		Category:            NewCategoryClient(cfg),
 		ChatRecords:         NewChatRecordsClient(cfg),
 		ChatSession:         NewChatSessionClient(cfg),
+		CompapiJob:          NewCompapiJobClient(cfg),
 		Contact:             NewContactClient(cfg),
 		CreditBalance:       NewCreditBalanceClient(cfg),
 		CreditUsage:         NewCreditUsageClient(cfg),
@@ -423,13 +429,14 @@ func (c *Client) Close() error {
 func (c *Client) Use(hooks ...Hook) {
 	for _, n := range []interface{ Use(...Hook) }{
 		c.Agent, c.AgentBase, c.AliyunAvatar, c.AllocAgent, c.ApiKey, c.BatchMsg,
-		c.Category, c.ChatRecords, c.ChatSession, c.Contact, c.CreditBalance,
-		c.CreditUsage, c.Employee, c.EmployeeConfig, c.Label, c.LabelRelationship,
-		c.LabelTagging, c.Message, c.MessageRecords, c.Msg, c.PayRecharge, c.Server,
-		c.SopNode, c.SopStage, c.SopTask, c.Token, c.Tutorial, c.UsageDetail,
-		c.UsageStatisticDay, c.UsageStatisticHour, c.UsageStatisticMonth, c.UsageTotal,
-		c.Whatsapp, c.WhatsappChannel, c.WorkExperience, c.WpChatroom,
-		c.WpChatroomMember, c.Wx, c.WxCard, c.WxCardUser, c.WxCardVisit,
+		c.Category, c.ChatRecords, c.ChatSession, c.CompapiJob, c.Contact,
+		c.CreditBalance, c.CreditUsage, c.Employee, c.EmployeeConfig, c.Label,
+		c.LabelRelationship, c.LabelTagging, c.Message, c.MessageRecords, c.Msg,
+		c.PayRecharge, c.Server, c.SopNode, c.SopStage, c.SopTask, c.Token, c.Tutorial,
+		c.UsageDetail, c.UsageStatisticDay, c.UsageStatisticHour,
+		c.UsageStatisticMonth, c.UsageTotal, c.Whatsapp, c.WhatsappChannel,
+		c.WorkExperience, c.WpChatroom, c.WpChatroomMember, c.Wx, c.WxCard,
+		c.WxCardUser, c.WxCardVisit,
 	} {
 		n.Use(hooks...)
 	}
@@ -440,13 +447,14 @@ func (c *Client) Use(hooks ...Hook) {
 func (c *Client) Intercept(interceptors ...Interceptor) {
 	for _, n := range []interface{ Intercept(...Interceptor) }{
 		c.Agent, c.AgentBase, c.AliyunAvatar, c.AllocAgent, c.ApiKey, c.BatchMsg,
-		c.Category, c.ChatRecords, c.ChatSession, c.Contact, c.CreditBalance,
-		c.CreditUsage, c.Employee, c.EmployeeConfig, c.Label, c.LabelRelationship,
-		c.LabelTagging, c.Message, c.MessageRecords, c.Msg, c.PayRecharge, c.Server,
-		c.SopNode, c.SopStage, c.SopTask, c.Token, c.Tutorial, c.UsageDetail,
-		c.UsageStatisticDay, c.UsageStatisticHour, c.UsageStatisticMonth, c.UsageTotal,
-		c.Whatsapp, c.WhatsappChannel, c.WorkExperience, c.WpChatroom,
-		c.WpChatroomMember, c.Wx, c.WxCard, c.WxCardUser, c.WxCardVisit,
+		c.Category, c.ChatRecords, c.ChatSession, c.CompapiJob, c.Contact,
+		c.CreditBalance, c.CreditUsage, c.Employee, c.EmployeeConfig, c.Label,
+		c.LabelRelationship, c.LabelTagging, c.Message, c.MessageRecords, c.Msg,
+		c.PayRecharge, c.Server, c.SopNode, c.SopStage, c.SopTask, c.Token, c.Tutorial,
+		c.UsageDetail, c.UsageStatisticDay, c.UsageStatisticHour,
+		c.UsageStatisticMonth, c.UsageTotal, c.Whatsapp, c.WhatsappChannel,
+		c.WorkExperience, c.WpChatroom, c.WpChatroomMember, c.Wx, c.WxCard,
+		c.WxCardUser, c.WxCardVisit,
 	} {
 		n.Intercept(interceptors...)
 	}
@@ -473,6 +481,8 @@ func (c *Client) Mutate(ctx context.Context, m Mutation) (Value, error) {
 		return c.ChatRecords.mutate(ctx, m)
 	case *ChatSessionMutation:
 		return c.ChatSession.mutate(ctx, m)
+	case *CompapiJobMutation:
+		return c.CompapiJob.mutate(ctx, m)
 	case *ContactMutation:
 		return c.Contact.mutate(ctx, m)
 	case *CreditBalanceMutation:
@@ -1851,6 +1861,139 @@ func (c *ChatSessionClient) mutate(ctx context.Context, m *ChatSessionMutation)
 	}
 }
 
+// CompapiJobClient is a client for the CompapiJob schema.
+type CompapiJobClient struct {
+	config
+}
+
+// NewCompapiJobClient returns a client for the CompapiJob from the given config.
+func NewCompapiJobClient(c config) *CompapiJobClient {
+	return &CompapiJobClient{config: c}
+}
+
+// Use adds a list of mutation hooks to the hooks stack.
+// A call to `Use(f, g, h)` equals to `compapijob.Hooks(f(g(h())))`.
+func (c *CompapiJobClient) Use(hooks ...Hook) {
+	c.hooks.CompapiJob = append(c.hooks.CompapiJob, hooks...)
+}
+
+// Intercept adds a list of query interceptors to the interceptors stack.
+// A call to `Intercept(f, g, h)` equals to `compapijob.Intercept(f(g(h())))`.
+func (c *CompapiJobClient) Intercept(interceptors ...Interceptor) {
+	c.inters.CompapiJob = append(c.inters.CompapiJob, interceptors...)
+}
+
+// Create returns a builder for creating a CompapiJob entity.
+func (c *CompapiJobClient) Create() *CompapiJobCreate {
+	mutation := newCompapiJobMutation(c.config, OpCreate)
+	return &CompapiJobCreate{config: c.config, hooks: c.Hooks(), mutation: mutation}
+}
+
+// CreateBulk returns a builder for creating a bulk of CompapiJob entities.
+func (c *CompapiJobClient) CreateBulk(builders ...*CompapiJobCreate) *CompapiJobCreateBulk {
+	return &CompapiJobCreateBulk{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 *CompapiJobClient) MapCreateBulk(slice any, setFunc func(*CompapiJobCreate, int)) *CompapiJobCreateBulk {
+	rv := reflect.ValueOf(slice)
+	if rv.Kind() != reflect.Slice {
+		return &CompapiJobCreateBulk{err: fmt.Errorf("calling to CompapiJobClient.MapCreateBulk with wrong type %T, need slice", slice)}
+	}
+	builders := make([]*CompapiJobCreate, rv.Len())
+	for i := 0; i < rv.Len(); i++ {
+		builders[i] = c.Create()
+		setFunc(builders[i], i)
+	}
+	return &CompapiJobCreateBulk{config: c.config, builders: builders}
+}
+
+// Update returns an update builder for CompapiJob.
+func (c *CompapiJobClient) Update() *CompapiJobUpdate {
+	mutation := newCompapiJobMutation(c.config, OpUpdate)
+	return &CompapiJobUpdate{config: c.config, hooks: c.Hooks(), mutation: mutation}
+}
+
+// UpdateOne returns an update builder for the given entity.
+func (c *CompapiJobClient) UpdateOne(cj *CompapiJob) *CompapiJobUpdateOne {
+	mutation := newCompapiJobMutation(c.config, OpUpdateOne, withCompapiJob(cj))
+	return &CompapiJobUpdateOne{config: c.config, hooks: c.Hooks(), mutation: mutation}
+}
+
+// UpdateOneID returns an update builder for the given id.
+func (c *CompapiJobClient) UpdateOneID(id uint64) *CompapiJobUpdateOne {
+	mutation := newCompapiJobMutation(c.config, OpUpdateOne, withCompapiJobID(id))
+	return &CompapiJobUpdateOne{config: c.config, hooks: c.Hooks(), mutation: mutation}
+}
+
+// Delete returns a delete builder for CompapiJob.
+func (c *CompapiJobClient) Delete() *CompapiJobDelete {
+	mutation := newCompapiJobMutation(c.config, OpDelete)
+	return &CompapiJobDelete{config: c.config, hooks: c.Hooks(), mutation: mutation}
+}
+
+// DeleteOne returns a builder for deleting the given entity.
+func (c *CompapiJobClient) DeleteOne(cj *CompapiJob) *CompapiJobDeleteOne {
+	return c.DeleteOneID(cj.ID)
+}
+
+// DeleteOneID returns a builder for deleting the given entity by its id.
+func (c *CompapiJobClient) DeleteOneID(id uint64) *CompapiJobDeleteOne {
+	builder := c.Delete().Where(compapijob.ID(id))
+	builder.mutation.id = &id
+	builder.mutation.op = OpDeleteOne
+	return &CompapiJobDeleteOne{builder}
+}
+
+// Query returns a query builder for CompapiJob.
+func (c *CompapiJobClient) Query() *CompapiJobQuery {
+	return &CompapiJobQuery{
+		config: c.config,
+		ctx:    &QueryContext{Type: TypeCompapiJob},
+		inters: c.Interceptors(),
+	}
+}
+
+// Get returns a CompapiJob entity by its id.
+func (c *CompapiJobClient) Get(ctx context.Context, id uint64) (*CompapiJob, error) {
+	return c.Query().Where(compapijob.ID(id)).Only(ctx)
+}
+
+// GetX is like Get, but panics if an error occurs.
+func (c *CompapiJobClient) GetX(ctx context.Context, id uint64) *CompapiJob {
+	obj, err := c.Get(ctx, id)
+	if err != nil {
+		panic(err)
+	}
+	return obj
+}
+
+// Hooks returns the client hooks.
+func (c *CompapiJobClient) Hooks() []Hook {
+	return c.hooks.CompapiJob
+}
+
+// Interceptors returns the client interceptors.
+func (c *CompapiJobClient) Interceptors() []Interceptor {
+	return c.inters.CompapiJob
+}
+
+func (c *CompapiJobClient) mutate(ctx context.Context, m *CompapiJobMutation) (Value, error) {
+	switch m.Op() {
+	case OpCreate:
+		return (&CompapiJobCreate{config: c.config, hooks: c.Hooks(), mutation: m}).Save(ctx)
+	case OpUpdate:
+		return (&CompapiJobUpdate{config: c.config, hooks: c.Hooks(), mutation: m}).Save(ctx)
+	case OpUpdateOne:
+		return (&CompapiJobUpdateOne{config: c.config, hooks: c.Hooks(), mutation: m}).Save(ctx)
+	case OpDelete, OpDeleteOne:
+		return (&CompapiJobDelete{config: c.config, hooks: c.Hooks(), mutation: m}).Exec(ctx)
+	default:
+		return nil, fmt.Errorf("ent: unknown CompapiJob mutation op: %q", m.Op())
+	}
+}
+
 // ContactClient is a client for the Contact schema.
 type ContactClient struct {
 	config
@@ -6527,8 +6670,8 @@ func (c *WxCardVisitClient) mutate(ctx context.Context, m *WxCardVisitMutation)
 type (
 	hooks struct {
 		Agent, AgentBase, AliyunAvatar, AllocAgent, ApiKey, BatchMsg, Category,
-		ChatRecords, ChatSession, Contact, CreditBalance, CreditUsage, Employee,
-		EmployeeConfig, Label, LabelRelationship, LabelTagging, Message,
+		ChatRecords, ChatSession, CompapiJob, Contact, CreditBalance, CreditUsage,
+		Employee, EmployeeConfig, Label, LabelRelationship, LabelTagging, Message,
 		MessageRecords, Msg, PayRecharge, Server, SopNode, SopStage, SopTask, Token,
 		Tutorial, UsageDetail, UsageStatisticDay, UsageStatisticHour,
 		UsageStatisticMonth, UsageTotal, Whatsapp, WhatsappChannel, WorkExperience,
@@ -6536,8 +6679,8 @@ type (
 	}
 	inters struct {
 		Agent, AgentBase, AliyunAvatar, AllocAgent, ApiKey, BatchMsg, Category,
-		ChatRecords, ChatSession, Contact, CreditBalance, CreditUsage, Employee,
-		EmployeeConfig, Label, LabelRelationship, LabelTagging, Message,
+		ChatRecords, ChatSession, CompapiJob, Contact, CreditBalance, CreditUsage,
+		Employee, EmployeeConfig, Label, LabelRelationship, LabelTagging, Message,
 		MessageRecords, Msg, PayRecharge, Server, SopNode, SopStage, SopTask, Token,
 		Tutorial, UsageDetail, UsageStatisticDay, UsageStatisticHour,
 		UsageStatisticMonth, UsageTotal, Whatsapp, WhatsappChannel, WorkExperience,

+ 233 - 0
ent/compapijob.go

@@ -0,0 +1,233 @@
+// Code generated by ent, DO NOT EDIT.
+
+package ent
+
+import (
+	"encoding/json"
+	"fmt"
+	"strings"
+	"time"
+	"wechat-api/ent/compapijob"
+	"wechat-api/ent/custom_types"
+
+	"entgo.io/ent"
+	"entgo.io/ent/dialect/sql"
+)
+
+// CompapiJob is the model entity for the CompapiJob schema.
+type CompapiJob 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"`
+	// Dist Time | 分发时间
+	DistAt time.Time `json:"dist_at,omitempty"`
+	// dist status | 分发状态 0 未 1 已
+	DistStatus int8 `json:"dist_status,omitempty"`
+	// callback_status | 回调状态 10 准备回调 20
+	CallbackStatus int8 `json:"callback_status,omitempty"`
+	// 异步执行回调地址
+	CallbackURL string `json:"callback_url,omitempty"`
+	// 请求参数结构JSON
+	RequestJSON custom_types.OriginalData `json:"request_json,omitempty"`
+	// 发起请求者的授权token
+	AuthToken string `json:"auth_token,omitempty"`
+	// 发起请求者的类型
+	EventType string `json:"event_type,omitempty"`
+	// workId在字典中的索引
+	WorkidIdx int8 `json:"workid_idx,omitempty"`
+	// 会话ID
+	ChatID string `json:"chat_id,omitempty"`
+	// retry count | 重试次数
+	RetryCount   int8 `json:"retry_count,omitempty"`
+	selectValues sql.SelectValues
+}
+
+// scanValues returns the types for scanning values from sql.Rows.
+func (*CompapiJob) scanValues(columns []string) ([]any, error) {
+	values := make([]any, len(columns))
+	for i := range columns {
+		switch columns[i] {
+		case compapijob.FieldRequestJSON:
+			values[i] = new([]byte)
+		case compapijob.FieldID, compapijob.FieldDistStatus, compapijob.FieldCallbackStatus, compapijob.FieldWorkidIdx, compapijob.FieldRetryCount:
+			values[i] = new(sql.NullInt64)
+		case compapijob.FieldCallbackURL, compapijob.FieldAuthToken, compapijob.FieldEventType, compapijob.FieldChatID:
+			values[i] = new(sql.NullString)
+		case compapijob.FieldCreatedAt, compapijob.FieldUpdatedAt, compapijob.FieldDistAt:
+			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 CompapiJob fields.
+func (cj *CompapiJob) 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 compapijob.FieldID:
+			value, ok := values[i].(*sql.NullInt64)
+			if !ok {
+				return fmt.Errorf("unexpected type %T for field id", value)
+			}
+			cj.ID = uint64(value.Int64)
+		case compapijob.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 {
+				cj.CreatedAt = value.Time
+			}
+		case compapijob.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 {
+				cj.UpdatedAt = value.Time
+			}
+		case compapijob.FieldDistAt:
+			if value, ok := values[i].(*sql.NullTime); !ok {
+				return fmt.Errorf("unexpected type %T for field dist_at", values[i])
+			} else if value.Valid {
+				cj.DistAt = value.Time
+			}
+		case compapijob.FieldDistStatus:
+			if value, ok := values[i].(*sql.NullInt64); !ok {
+				return fmt.Errorf("unexpected type %T for field dist_status", values[i])
+			} else if value.Valid {
+				cj.DistStatus = int8(value.Int64)
+			}
+		case compapijob.FieldCallbackStatus:
+			if value, ok := values[i].(*sql.NullInt64); !ok {
+				return fmt.Errorf("unexpected type %T for field callback_status", values[i])
+			} else if value.Valid {
+				cj.CallbackStatus = int8(value.Int64)
+			}
+		case compapijob.FieldCallbackURL:
+			if value, ok := values[i].(*sql.NullString); !ok {
+				return fmt.Errorf("unexpected type %T for field callback_url", values[i])
+			} else if value.Valid {
+				cj.CallbackURL = value.String
+			}
+		case compapijob.FieldRequestJSON:
+			if value, ok := values[i].(*[]byte); !ok {
+				return fmt.Errorf("unexpected type %T for field request_json", values[i])
+			} else if value != nil && len(*value) > 0 {
+				if err := json.Unmarshal(*value, &cj.RequestJSON); err != nil {
+					return fmt.Errorf("unmarshal field request_json: %w", err)
+				}
+			}
+		case compapijob.FieldAuthToken:
+			if value, ok := values[i].(*sql.NullString); !ok {
+				return fmt.Errorf("unexpected type %T for field auth_token", values[i])
+			} else if value.Valid {
+				cj.AuthToken = value.String
+			}
+		case compapijob.FieldEventType:
+			if value, ok := values[i].(*sql.NullString); !ok {
+				return fmt.Errorf("unexpected type %T for field event_type", values[i])
+			} else if value.Valid {
+				cj.EventType = value.String
+			}
+		case compapijob.FieldWorkidIdx:
+			if value, ok := values[i].(*sql.NullInt64); !ok {
+				return fmt.Errorf("unexpected type %T for field workid_idx", values[i])
+			} else if value.Valid {
+				cj.WorkidIdx = int8(value.Int64)
+			}
+		case compapijob.FieldChatID:
+			if value, ok := values[i].(*sql.NullString); !ok {
+				return fmt.Errorf("unexpected type %T for field chat_id", values[i])
+			} else if value.Valid {
+				cj.ChatID = value.String
+			}
+		case compapijob.FieldRetryCount:
+			if value, ok := values[i].(*sql.NullInt64); !ok {
+				return fmt.Errorf("unexpected type %T for field retry_count", values[i])
+			} else if value.Valid {
+				cj.RetryCount = int8(value.Int64)
+			}
+		default:
+			cj.selectValues.Set(columns[i], values[i])
+		}
+	}
+	return nil
+}
+
+// Value returns the ent.Value that was dynamically selected and assigned to the CompapiJob.
+// This includes values selected through modifiers, order, etc.
+func (cj *CompapiJob) Value(name string) (ent.Value, error) {
+	return cj.selectValues.Get(name)
+}
+
+// Update returns a builder for updating this CompapiJob.
+// Note that you need to call CompapiJob.Unwrap() before calling this method if this CompapiJob
+// was returned from a transaction, and the transaction was committed or rolled back.
+func (cj *CompapiJob) Update() *CompapiJobUpdateOne {
+	return NewCompapiJobClient(cj.config).UpdateOne(cj)
+}
+
+// Unwrap unwraps the CompapiJob 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 (cj *CompapiJob) Unwrap() *CompapiJob {
+	_tx, ok := cj.config.driver.(*txDriver)
+	if !ok {
+		panic("ent: CompapiJob is not a transactional entity")
+	}
+	cj.config.driver = _tx.drv
+	return cj
+}
+
+// String implements the fmt.Stringer.
+func (cj *CompapiJob) String() string {
+	var builder strings.Builder
+	builder.WriteString("CompapiJob(")
+	builder.WriteString(fmt.Sprintf("id=%v, ", cj.ID))
+	builder.WriteString("created_at=")
+	builder.WriteString(cj.CreatedAt.Format(time.ANSIC))
+	builder.WriteString(", ")
+	builder.WriteString("updated_at=")
+	builder.WriteString(cj.UpdatedAt.Format(time.ANSIC))
+	builder.WriteString(", ")
+	builder.WriteString("dist_at=")
+	builder.WriteString(cj.DistAt.Format(time.ANSIC))
+	builder.WriteString(", ")
+	builder.WriteString("dist_status=")
+	builder.WriteString(fmt.Sprintf("%v", cj.DistStatus))
+	builder.WriteString(", ")
+	builder.WriteString("callback_status=")
+	builder.WriteString(fmt.Sprintf("%v", cj.CallbackStatus))
+	builder.WriteString(", ")
+	builder.WriteString("callback_url=")
+	builder.WriteString(cj.CallbackURL)
+	builder.WriteString(", ")
+	builder.WriteString("request_json=")
+	builder.WriteString(fmt.Sprintf("%v", cj.RequestJSON))
+	builder.WriteString(", ")
+	builder.WriteString("auth_token=")
+	builder.WriteString(cj.AuthToken)
+	builder.WriteString(", ")
+	builder.WriteString("event_type=")
+	builder.WriteString(cj.EventType)
+	builder.WriteString(", ")
+	builder.WriteString("workid_idx=")
+	builder.WriteString(fmt.Sprintf("%v", cj.WorkidIdx))
+	builder.WriteString(", ")
+	builder.WriteString("chat_id=")
+	builder.WriteString(cj.ChatID)
+	builder.WriteString(", ")
+	builder.WriteString("retry_count=")
+	builder.WriteString(fmt.Sprintf("%v", cj.RetryCount))
+	builder.WriteByte(')')
+	return builder.String()
+}
+
+// CompapiJobs is a parsable slice of CompapiJob.
+type CompapiJobs []*CompapiJob

+ 155 - 0
ent/compapijob/compapijob.go

@@ -0,0 +1,155 @@
+// Code generated by ent, DO NOT EDIT.
+
+package compapijob
+
+import (
+	"time"
+
+	"entgo.io/ent/dialect/sql"
+)
+
+const (
+	// Label holds the string label denoting the compapijob type in the database.
+	Label = "compapi_job"
+	// 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"
+	// FieldDistAt holds the string denoting the dist_at field in the database.
+	FieldDistAt = "dist_at"
+	// FieldDistStatus holds the string denoting the dist_status field in the database.
+	FieldDistStatus = "dist_status"
+	// FieldCallbackStatus holds the string denoting the callback_status field in the database.
+	FieldCallbackStatus = "callback_status"
+	// FieldCallbackURL holds the string denoting the callback_url field in the database.
+	FieldCallbackURL = "callback_url"
+	// FieldRequestJSON holds the string denoting the request_json field in the database.
+	FieldRequestJSON = "request_json"
+	// FieldAuthToken holds the string denoting the auth_token field in the database.
+	FieldAuthToken = "auth_token"
+	// FieldEventType holds the string denoting the event_type field in the database.
+	FieldEventType = "event_type"
+	// FieldWorkidIdx holds the string denoting the workid_idx field in the database.
+	FieldWorkidIdx = "workid_idx"
+	// FieldChatID holds the string denoting the chat_id field in the database.
+	FieldChatID = "chat_id"
+	// FieldRetryCount holds the string denoting the retry_count field in the database.
+	FieldRetryCount = "retry_count"
+	// Table holds the table name of the compapijob in the database.
+	Table = "compapi_job"
+)
+
+// Columns holds all SQL columns for compapijob fields.
+var Columns = []string{
+	FieldID,
+	FieldCreatedAt,
+	FieldUpdatedAt,
+	FieldDistAt,
+	FieldDistStatus,
+	FieldCallbackStatus,
+	FieldCallbackURL,
+	FieldRequestJSON,
+	FieldAuthToken,
+	FieldEventType,
+	FieldWorkidIdx,
+	FieldChatID,
+	FieldRetryCount,
+}
+
+// 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
+	// DefaultDistStatus holds the default value on creation for the "dist_status" field.
+	DefaultDistStatus int8
+	// DefaultCallbackStatus holds the default value on creation for the "callback_status" field.
+	DefaultCallbackStatus int8
+	// DefaultAuthToken holds the default value on creation for the "auth_token" field.
+	DefaultAuthToken string
+	// DefaultEventType holds the default value on creation for the "event_type" field.
+	DefaultEventType string
+	// DefaultWorkidIdx holds the default value on creation for the "workid_idx" field.
+	DefaultWorkidIdx int8
+	// DefaultChatID holds the default value on creation for the "chat_id" field.
+	DefaultChatID string
+	// DefaultRetryCount holds the default value on creation for the "retry_count" field.
+	DefaultRetryCount int8
+)
+
+// OrderOption defines the ordering options for the CompapiJob 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()
+}
+
+// ByDistAt orders the results by the dist_at field.
+func ByDistAt(opts ...sql.OrderTermOption) OrderOption {
+	return sql.OrderByField(FieldDistAt, opts...).ToFunc()
+}
+
+// ByDistStatus orders the results by the dist_status field.
+func ByDistStatus(opts ...sql.OrderTermOption) OrderOption {
+	return sql.OrderByField(FieldDistStatus, opts...).ToFunc()
+}
+
+// ByCallbackStatus orders the results by the callback_status field.
+func ByCallbackStatus(opts ...sql.OrderTermOption) OrderOption {
+	return sql.OrderByField(FieldCallbackStatus, opts...).ToFunc()
+}
+
+// ByCallbackURL orders the results by the callback_url field.
+func ByCallbackURL(opts ...sql.OrderTermOption) OrderOption {
+	return sql.OrderByField(FieldCallbackURL, opts...).ToFunc()
+}
+
+// ByAuthToken orders the results by the auth_token field.
+func ByAuthToken(opts ...sql.OrderTermOption) OrderOption {
+	return sql.OrderByField(FieldAuthToken, opts...).ToFunc()
+}
+
+// ByEventType orders the results by the event_type field.
+func ByEventType(opts ...sql.OrderTermOption) OrderOption {
+	return sql.OrderByField(FieldEventType, opts...).ToFunc()
+}
+
+// ByWorkidIdx orders the results by the workid_idx field.
+func ByWorkidIdx(opts ...sql.OrderTermOption) OrderOption {
+	return sql.OrderByField(FieldWorkidIdx, opts...).ToFunc()
+}
+
+// ByChatID orders the results by the chat_id field.
+func ByChatID(opts ...sql.OrderTermOption) OrderOption {
+	return sql.OrderByField(FieldChatID, opts...).ToFunc()
+}
+
+// ByRetryCount orders the results by the retry_count field.
+func ByRetryCount(opts ...sql.OrderTermOption) OrderOption {
+	return sql.OrderByField(FieldRetryCount, opts...).ToFunc()
+}

+ 725 - 0
ent/compapijob/where.go

@@ -0,0 +1,725 @@
+// Code generated by ent, DO NOT EDIT.
+
+package compapijob
+
+import (
+	"time"
+	"wechat-api/ent/predicate"
+
+	"entgo.io/ent/dialect/sql"
+)
+
+// ID filters vertices based on their ID field.
+func ID(id uint64) predicate.CompapiJob {
+	return predicate.CompapiJob(sql.FieldEQ(FieldID, id))
+}
+
+// IDEQ applies the EQ predicate on the ID field.
+func IDEQ(id uint64) predicate.CompapiJob {
+	return predicate.CompapiJob(sql.FieldEQ(FieldID, id))
+}
+
+// IDNEQ applies the NEQ predicate on the ID field.
+func IDNEQ(id uint64) predicate.CompapiJob {
+	return predicate.CompapiJob(sql.FieldNEQ(FieldID, id))
+}
+
+// IDIn applies the In predicate on the ID field.
+func IDIn(ids ...uint64) predicate.CompapiJob {
+	return predicate.CompapiJob(sql.FieldIn(FieldID, ids...))
+}
+
+// IDNotIn applies the NotIn predicate on the ID field.
+func IDNotIn(ids ...uint64) predicate.CompapiJob {
+	return predicate.CompapiJob(sql.FieldNotIn(FieldID, ids...))
+}
+
+// IDGT applies the GT predicate on the ID field.
+func IDGT(id uint64) predicate.CompapiJob {
+	return predicate.CompapiJob(sql.FieldGT(FieldID, id))
+}
+
+// IDGTE applies the GTE predicate on the ID field.
+func IDGTE(id uint64) predicate.CompapiJob {
+	return predicate.CompapiJob(sql.FieldGTE(FieldID, id))
+}
+
+// IDLT applies the LT predicate on the ID field.
+func IDLT(id uint64) predicate.CompapiJob {
+	return predicate.CompapiJob(sql.FieldLT(FieldID, id))
+}
+
+// IDLTE applies the LTE predicate on the ID field.
+func IDLTE(id uint64) predicate.CompapiJob {
+	return predicate.CompapiJob(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.CompapiJob {
+	return predicate.CompapiJob(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.CompapiJob {
+	return predicate.CompapiJob(sql.FieldEQ(FieldUpdatedAt, v))
+}
+
+// DistAt applies equality check predicate on the "dist_at" field. It's identical to DistAtEQ.
+func DistAt(v time.Time) predicate.CompapiJob {
+	return predicate.CompapiJob(sql.FieldEQ(FieldDistAt, v))
+}
+
+// DistStatus applies equality check predicate on the "dist_status" field. It's identical to DistStatusEQ.
+func DistStatus(v int8) predicate.CompapiJob {
+	return predicate.CompapiJob(sql.FieldEQ(FieldDistStatus, v))
+}
+
+// CallbackStatus applies equality check predicate on the "callback_status" field. It's identical to CallbackStatusEQ.
+func CallbackStatus(v int8) predicate.CompapiJob {
+	return predicate.CompapiJob(sql.FieldEQ(FieldCallbackStatus, v))
+}
+
+// CallbackURL applies equality check predicate on the "callback_url" field. It's identical to CallbackURLEQ.
+func CallbackURL(v string) predicate.CompapiJob {
+	return predicate.CompapiJob(sql.FieldEQ(FieldCallbackURL, v))
+}
+
+// AuthToken applies equality check predicate on the "auth_token" field. It's identical to AuthTokenEQ.
+func AuthToken(v string) predicate.CompapiJob {
+	return predicate.CompapiJob(sql.FieldEQ(FieldAuthToken, v))
+}
+
+// EventType applies equality check predicate on the "event_type" field. It's identical to EventTypeEQ.
+func EventType(v string) predicate.CompapiJob {
+	return predicate.CompapiJob(sql.FieldEQ(FieldEventType, v))
+}
+
+// WorkidIdx applies equality check predicate on the "workid_idx" field. It's identical to WorkidIdxEQ.
+func WorkidIdx(v int8) predicate.CompapiJob {
+	return predicate.CompapiJob(sql.FieldEQ(FieldWorkidIdx, v))
+}
+
+// ChatID applies equality check predicate on the "chat_id" field. It's identical to ChatIDEQ.
+func ChatID(v string) predicate.CompapiJob {
+	return predicate.CompapiJob(sql.FieldEQ(FieldChatID, v))
+}
+
+// RetryCount applies equality check predicate on the "retry_count" field. It's identical to RetryCountEQ.
+func RetryCount(v int8) predicate.CompapiJob {
+	return predicate.CompapiJob(sql.FieldEQ(FieldRetryCount, v))
+}
+
+// CreatedAtEQ applies the EQ predicate on the "created_at" field.
+func CreatedAtEQ(v time.Time) predicate.CompapiJob {
+	return predicate.CompapiJob(sql.FieldEQ(FieldCreatedAt, v))
+}
+
+// CreatedAtNEQ applies the NEQ predicate on the "created_at" field.
+func CreatedAtNEQ(v time.Time) predicate.CompapiJob {
+	return predicate.CompapiJob(sql.FieldNEQ(FieldCreatedAt, v))
+}
+
+// CreatedAtIn applies the In predicate on the "created_at" field.
+func CreatedAtIn(vs ...time.Time) predicate.CompapiJob {
+	return predicate.CompapiJob(sql.FieldIn(FieldCreatedAt, vs...))
+}
+
+// CreatedAtNotIn applies the NotIn predicate on the "created_at" field.
+func CreatedAtNotIn(vs ...time.Time) predicate.CompapiJob {
+	return predicate.CompapiJob(sql.FieldNotIn(FieldCreatedAt, vs...))
+}
+
+// CreatedAtGT applies the GT predicate on the "created_at" field.
+func CreatedAtGT(v time.Time) predicate.CompapiJob {
+	return predicate.CompapiJob(sql.FieldGT(FieldCreatedAt, v))
+}
+
+// CreatedAtGTE applies the GTE predicate on the "created_at" field.
+func CreatedAtGTE(v time.Time) predicate.CompapiJob {
+	return predicate.CompapiJob(sql.FieldGTE(FieldCreatedAt, v))
+}
+
+// CreatedAtLT applies the LT predicate on the "created_at" field.
+func CreatedAtLT(v time.Time) predicate.CompapiJob {
+	return predicate.CompapiJob(sql.FieldLT(FieldCreatedAt, v))
+}
+
+// CreatedAtLTE applies the LTE predicate on the "created_at" field.
+func CreatedAtLTE(v time.Time) predicate.CompapiJob {
+	return predicate.CompapiJob(sql.FieldLTE(FieldCreatedAt, v))
+}
+
+// UpdatedAtEQ applies the EQ predicate on the "updated_at" field.
+func UpdatedAtEQ(v time.Time) predicate.CompapiJob {
+	return predicate.CompapiJob(sql.FieldEQ(FieldUpdatedAt, v))
+}
+
+// UpdatedAtNEQ applies the NEQ predicate on the "updated_at" field.
+func UpdatedAtNEQ(v time.Time) predicate.CompapiJob {
+	return predicate.CompapiJob(sql.FieldNEQ(FieldUpdatedAt, v))
+}
+
+// UpdatedAtIn applies the In predicate on the "updated_at" field.
+func UpdatedAtIn(vs ...time.Time) predicate.CompapiJob {
+	return predicate.CompapiJob(sql.FieldIn(FieldUpdatedAt, vs...))
+}
+
+// UpdatedAtNotIn applies the NotIn predicate on the "updated_at" field.
+func UpdatedAtNotIn(vs ...time.Time) predicate.CompapiJob {
+	return predicate.CompapiJob(sql.FieldNotIn(FieldUpdatedAt, vs...))
+}
+
+// UpdatedAtGT applies the GT predicate on the "updated_at" field.
+func UpdatedAtGT(v time.Time) predicate.CompapiJob {
+	return predicate.CompapiJob(sql.FieldGT(FieldUpdatedAt, v))
+}
+
+// UpdatedAtGTE applies the GTE predicate on the "updated_at" field.
+func UpdatedAtGTE(v time.Time) predicate.CompapiJob {
+	return predicate.CompapiJob(sql.FieldGTE(FieldUpdatedAt, v))
+}
+
+// UpdatedAtLT applies the LT predicate on the "updated_at" field.
+func UpdatedAtLT(v time.Time) predicate.CompapiJob {
+	return predicate.CompapiJob(sql.FieldLT(FieldUpdatedAt, v))
+}
+
+// UpdatedAtLTE applies the LTE predicate on the "updated_at" field.
+func UpdatedAtLTE(v time.Time) predicate.CompapiJob {
+	return predicate.CompapiJob(sql.FieldLTE(FieldUpdatedAt, v))
+}
+
+// DistAtEQ applies the EQ predicate on the "dist_at" field.
+func DistAtEQ(v time.Time) predicate.CompapiJob {
+	return predicate.CompapiJob(sql.FieldEQ(FieldDistAt, v))
+}
+
+// DistAtNEQ applies the NEQ predicate on the "dist_at" field.
+func DistAtNEQ(v time.Time) predicate.CompapiJob {
+	return predicate.CompapiJob(sql.FieldNEQ(FieldDistAt, v))
+}
+
+// DistAtIn applies the In predicate on the "dist_at" field.
+func DistAtIn(vs ...time.Time) predicate.CompapiJob {
+	return predicate.CompapiJob(sql.FieldIn(FieldDistAt, vs...))
+}
+
+// DistAtNotIn applies the NotIn predicate on the "dist_at" field.
+func DistAtNotIn(vs ...time.Time) predicate.CompapiJob {
+	return predicate.CompapiJob(sql.FieldNotIn(FieldDistAt, vs...))
+}
+
+// DistAtGT applies the GT predicate on the "dist_at" field.
+func DistAtGT(v time.Time) predicate.CompapiJob {
+	return predicate.CompapiJob(sql.FieldGT(FieldDistAt, v))
+}
+
+// DistAtGTE applies the GTE predicate on the "dist_at" field.
+func DistAtGTE(v time.Time) predicate.CompapiJob {
+	return predicate.CompapiJob(sql.FieldGTE(FieldDistAt, v))
+}
+
+// DistAtLT applies the LT predicate on the "dist_at" field.
+func DistAtLT(v time.Time) predicate.CompapiJob {
+	return predicate.CompapiJob(sql.FieldLT(FieldDistAt, v))
+}
+
+// DistAtLTE applies the LTE predicate on the "dist_at" field.
+func DistAtLTE(v time.Time) predicate.CompapiJob {
+	return predicate.CompapiJob(sql.FieldLTE(FieldDistAt, v))
+}
+
+// DistAtIsNil applies the IsNil predicate on the "dist_at" field.
+func DistAtIsNil() predicate.CompapiJob {
+	return predicate.CompapiJob(sql.FieldIsNull(FieldDistAt))
+}
+
+// DistAtNotNil applies the NotNil predicate on the "dist_at" field.
+func DistAtNotNil() predicate.CompapiJob {
+	return predicate.CompapiJob(sql.FieldNotNull(FieldDistAt))
+}
+
+// DistStatusEQ applies the EQ predicate on the "dist_status" field.
+func DistStatusEQ(v int8) predicate.CompapiJob {
+	return predicate.CompapiJob(sql.FieldEQ(FieldDistStatus, v))
+}
+
+// DistStatusNEQ applies the NEQ predicate on the "dist_status" field.
+func DistStatusNEQ(v int8) predicate.CompapiJob {
+	return predicate.CompapiJob(sql.FieldNEQ(FieldDistStatus, v))
+}
+
+// DistStatusIn applies the In predicate on the "dist_status" field.
+func DistStatusIn(vs ...int8) predicate.CompapiJob {
+	return predicate.CompapiJob(sql.FieldIn(FieldDistStatus, vs...))
+}
+
+// DistStatusNotIn applies the NotIn predicate on the "dist_status" field.
+func DistStatusNotIn(vs ...int8) predicate.CompapiJob {
+	return predicate.CompapiJob(sql.FieldNotIn(FieldDistStatus, vs...))
+}
+
+// DistStatusGT applies the GT predicate on the "dist_status" field.
+func DistStatusGT(v int8) predicate.CompapiJob {
+	return predicate.CompapiJob(sql.FieldGT(FieldDistStatus, v))
+}
+
+// DistStatusGTE applies the GTE predicate on the "dist_status" field.
+func DistStatusGTE(v int8) predicate.CompapiJob {
+	return predicate.CompapiJob(sql.FieldGTE(FieldDistStatus, v))
+}
+
+// DistStatusLT applies the LT predicate on the "dist_status" field.
+func DistStatusLT(v int8) predicate.CompapiJob {
+	return predicate.CompapiJob(sql.FieldLT(FieldDistStatus, v))
+}
+
+// DistStatusLTE applies the LTE predicate on the "dist_status" field.
+func DistStatusLTE(v int8) predicate.CompapiJob {
+	return predicate.CompapiJob(sql.FieldLTE(FieldDistStatus, v))
+}
+
+// DistStatusIsNil applies the IsNil predicate on the "dist_status" field.
+func DistStatusIsNil() predicate.CompapiJob {
+	return predicate.CompapiJob(sql.FieldIsNull(FieldDistStatus))
+}
+
+// DistStatusNotNil applies the NotNil predicate on the "dist_status" field.
+func DistStatusNotNil() predicate.CompapiJob {
+	return predicate.CompapiJob(sql.FieldNotNull(FieldDistStatus))
+}
+
+// CallbackStatusEQ applies the EQ predicate on the "callback_status" field.
+func CallbackStatusEQ(v int8) predicate.CompapiJob {
+	return predicate.CompapiJob(sql.FieldEQ(FieldCallbackStatus, v))
+}
+
+// CallbackStatusNEQ applies the NEQ predicate on the "callback_status" field.
+func CallbackStatusNEQ(v int8) predicate.CompapiJob {
+	return predicate.CompapiJob(sql.FieldNEQ(FieldCallbackStatus, v))
+}
+
+// CallbackStatusIn applies the In predicate on the "callback_status" field.
+func CallbackStatusIn(vs ...int8) predicate.CompapiJob {
+	return predicate.CompapiJob(sql.FieldIn(FieldCallbackStatus, vs...))
+}
+
+// CallbackStatusNotIn applies the NotIn predicate on the "callback_status" field.
+func CallbackStatusNotIn(vs ...int8) predicate.CompapiJob {
+	return predicate.CompapiJob(sql.FieldNotIn(FieldCallbackStatus, vs...))
+}
+
+// CallbackStatusGT applies the GT predicate on the "callback_status" field.
+func CallbackStatusGT(v int8) predicate.CompapiJob {
+	return predicate.CompapiJob(sql.FieldGT(FieldCallbackStatus, v))
+}
+
+// CallbackStatusGTE applies the GTE predicate on the "callback_status" field.
+func CallbackStatusGTE(v int8) predicate.CompapiJob {
+	return predicate.CompapiJob(sql.FieldGTE(FieldCallbackStatus, v))
+}
+
+// CallbackStatusLT applies the LT predicate on the "callback_status" field.
+func CallbackStatusLT(v int8) predicate.CompapiJob {
+	return predicate.CompapiJob(sql.FieldLT(FieldCallbackStatus, v))
+}
+
+// CallbackStatusLTE applies the LTE predicate on the "callback_status" field.
+func CallbackStatusLTE(v int8) predicate.CompapiJob {
+	return predicate.CompapiJob(sql.FieldLTE(FieldCallbackStatus, v))
+}
+
+// CallbackStatusIsNil applies the IsNil predicate on the "callback_status" field.
+func CallbackStatusIsNil() predicate.CompapiJob {
+	return predicate.CompapiJob(sql.FieldIsNull(FieldCallbackStatus))
+}
+
+// CallbackStatusNotNil applies the NotNil predicate on the "callback_status" field.
+func CallbackStatusNotNil() predicate.CompapiJob {
+	return predicate.CompapiJob(sql.FieldNotNull(FieldCallbackStatus))
+}
+
+// CallbackURLEQ applies the EQ predicate on the "callback_url" field.
+func CallbackURLEQ(v string) predicate.CompapiJob {
+	return predicate.CompapiJob(sql.FieldEQ(FieldCallbackURL, v))
+}
+
+// CallbackURLNEQ applies the NEQ predicate on the "callback_url" field.
+func CallbackURLNEQ(v string) predicate.CompapiJob {
+	return predicate.CompapiJob(sql.FieldNEQ(FieldCallbackURL, v))
+}
+
+// CallbackURLIn applies the In predicate on the "callback_url" field.
+func CallbackURLIn(vs ...string) predicate.CompapiJob {
+	return predicate.CompapiJob(sql.FieldIn(FieldCallbackURL, vs...))
+}
+
+// CallbackURLNotIn applies the NotIn predicate on the "callback_url" field.
+func CallbackURLNotIn(vs ...string) predicate.CompapiJob {
+	return predicate.CompapiJob(sql.FieldNotIn(FieldCallbackURL, vs...))
+}
+
+// CallbackURLGT applies the GT predicate on the "callback_url" field.
+func CallbackURLGT(v string) predicate.CompapiJob {
+	return predicate.CompapiJob(sql.FieldGT(FieldCallbackURL, v))
+}
+
+// CallbackURLGTE applies the GTE predicate on the "callback_url" field.
+func CallbackURLGTE(v string) predicate.CompapiJob {
+	return predicate.CompapiJob(sql.FieldGTE(FieldCallbackURL, v))
+}
+
+// CallbackURLLT applies the LT predicate on the "callback_url" field.
+func CallbackURLLT(v string) predicate.CompapiJob {
+	return predicate.CompapiJob(sql.FieldLT(FieldCallbackURL, v))
+}
+
+// CallbackURLLTE applies the LTE predicate on the "callback_url" field.
+func CallbackURLLTE(v string) predicate.CompapiJob {
+	return predicate.CompapiJob(sql.FieldLTE(FieldCallbackURL, v))
+}
+
+// CallbackURLContains applies the Contains predicate on the "callback_url" field.
+func CallbackURLContains(v string) predicate.CompapiJob {
+	return predicate.CompapiJob(sql.FieldContains(FieldCallbackURL, v))
+}
+
+// CallbackURLHasPrefix applies the HasPrefix predicate on the "callback_url" field.
+func CallbackURLHasPrefix(v string) predicate.CompapiJob {
+	return predicate.CompapiJob(sql.FieldHasPrefix(FieldCallbackURL, v))
+}
+
+// CallbackURLHasSuffix applies the HasSuffix predicate on the "callback_url" field.
+func CallbackURLHasSuffix(v string) predicate.CompapiJob {
+	return predicate.CompapiJob(sql.FieldHasSuffix(FieldCallbackURL, v))
+}
+
+// CallbackURLEqualFold applies the EqualFold predicate on the "callback_url" field.
+func CallbackURLEqualFold(v string) predicate.CompapiJob {
+	return predicate.CompapiJob(sql.FieldEqualFold(FieldCallbackURL, v))
+}
+
+// CallbackURLContainsFold applies the ContainsFold predicate on the "callback_url" field.
+func CallbackURLContainsFold(v string) predicate.CompapiJob {
+	return predicate.CompapiJob(sql.FieldContainsFold(FieldCallbackURL, v))
+}
+
+// AuthTokenEQ applies the EQ predicate on the "auth_token" field.
+func AuthTokenEQ(v string) predicate.CompapiJob {
+	return predicate.CompapiJob(sql.FieldEQ(FieldAuthToken, v))
+}
+
+// AuthTokenNEQ applies the NEQ predicate on the "auth_token" field.
+func AuthTokenNEQ(v string) predicate.CompapiJob {
+	return predicate.CompapiJob(sql.FieldNEQ(FieldAuthToken, v))
+}
+
+// AuthTokenIn applies the In predicate on the "auth_token" field.
+func AuthTokenIn(vs ...string) predicate.CompapiJob {
+	return predicate.CompapiJob(sql.FieldIn(FieldAuthToken, vs...))
+}
+
+// AuthTokenNotIn applies the NotIn predicate on the "auth_token" field.
+func AuthTokenNotIn(vs ...string) predicate.CompapiJob {
+	return predicate.CompapiJob(sql.FieldNotIn(FieldAuthToken, vs...))
+}
+
+// AuthTokenGT applies the GT predicate on the "auth_token" field.
+func AuthTokenGT(v string) predicate.CompapiJob {
+	return predicate.CompapiJob(sql.FieldGT(FieldAuthToken, v))
+}
+
+// AuthTokenGTE applies the GTE predicate on the "auth_token" field.
+func AuthTokenGTE(v string) predicate.CompapiJob {
+	return predicate.CompapiJob(sql.FieldGTE(FieldAuthToken, v))
+}
+
+// AuthTokenLT applies the LT predicate on the "auth_token" field.
+func AuthTokenLT(v string) predicate.CompapiJob {
+	return predicate.CompapiJob(sql.FieldLT(FieldAuthToken, v))
+}
+
+// AuthTokenLTE applies the LTE predicate on the "auth_token" field.
+func AuthTokenLTE(v string) predicate.CompapiJob {
+	return predicate.CompapiJob(sql.FieldLTE(FieldAuthToken, v))
+}
+
+// AuthTokenContains applies the Contains predicate on the "auth_token" field.
+func AuthTokenContains(v string) predicate.CompapiJob {
+	return predicate.CompapiJob(sql.FieldContains(FieldAuthToken, v))
+}
+
+// AuthTokenHasPrefix applies the HasPrefix predicate on the "auth_token" field.
+func AuthTokenHasPrefix(v string) predicate.CompapiJob {
+	return predicate.CompapiJob(sql.FieldHasPrefix(FieldAuthToken, v))
+}
+
+// AuthTokenHasSuffix applies the HasSuffix predicate on the "auth_token" field.
+func AuthTokenHasSuffix(v string) predicate.CompapiJob {
+	return predicate.CompapiJob(sql.FieldHasSuffix(FieldAuthToken, v))
+}
+
+// AuthTokenEqualFold applies the EqualFold predicate on the "auth_token" field.
+func AuthTokenEqualFold(v string) predicate.CompapiJob {
+	return predicate.CompapiJob(sql.FieldEqualFold(FieldAuthToken, v))
+}
+
+// AuthTokenContainsFold applies the ContainsFold predicate on the "auth_token" field.
+func AuthTokenContainsFold(v string) predicate.CompapiJob {
+	return predicate.CompapiJob(sql.FieldContainsFold(FieldAuthToken, v))
+}
+
+// EventTypeEQ applies the EQ predicate on the "event_type" field.
+func EventTypeEQ(v string) predicate.CompapiJob {
+	return predicate.CompapiJob(sql.FieldEQ(FieldEventType, v))
+}
+
+// EventTypeNEQ applies the NEQ predicate on the "event_type" field.
+func EventTypeNEQ(v string) predicate.CompapiJob {
+	return predicate.CompapiJob(sql.FieldNEQ(FieldEventType, v))
+}
+
+// EventTypeIn applies the In predicate on the "event_type" field.
+func EventTypeIn(vs ...string) predicate.CompapiJob {
+	return predicate.CompapiJob(sql.FieldIn(FieldEventType, vs...))
+}
+
+// EventTypeNotIn applies the NotIn predicate on the "event_type" field.
+func EventTypeNotIn(vs ...string) predicate.CompapiJob {
+	return predicate.CompapiJob(sql.FieldNotIn(FieldEventType, vs...))
+}
+
+// EventTypeGT applies the GT predicate on the "event_type" field.
+func EventTypeGT(v string) predicate.CompapiJob {
+	return predicate.CompapiJob(sql.FieldGT(FieldEventType, v))
+}
+
+// EventTypeGTE applies the GTE predicate on the "event_type" field.
+func EventTypeGTE(v string) predicate.CompapiJob {
+	return predicate.CompapiJob(sql.FieldGTE(FieldEventType, v))
+}
+
+// EventTypeLT applies the LT predicate on the "event_type" field.
+func EventTypeLT(v string) predicate.CompapiJob {
+	return predicate.CompapiJob(sql.FieldLT(FieldEventType, v))
+}
+
+// EventTypeLTE applies the LTE predicate on the "event_type" field.
+func EventTypeLTE(v string) predicate.CompapiJob {
+	return predicate.CompapiJob(sql.FieldLTE(FieldEventType, v))
+}
+
+// EventTypeContains applies the Contains predicate on the "event_type" field.
+func EventTypeContains(v string) predicate.CompapiJob {
+	return predicate.CompapiJob(sql.FieldContains(FieldEventType, v))
+}
+
+// EventTypeHasPrefix applies the HasPrefix predicate on the "event_type" field.
+func EventTypeHasPrefix(v string) predicate.CompapiJob {
+	return predicate.CompapiJob(sql.FieldHasPrefix(FieldEventType, v))
+}
+
+// EventTypeHasSuffix applies the HasSuffix predicate on the "event_type" field.
+func EventTypeHasSuffix(v string) predicate.CompapiJob {
+	return predicate.CompapiJob(sql.FieldHasSuffix(FieldEventType, v))
+}
+
+// EventTypeEqualFold applies the EqualFold predicate on the "event_type" field.
+func EventTypeEqualFold(v string) predicate.CompapiJob {
+	return predicate.CompapiJob(sql.FieldEqualFold(FieldEventType, v))
+}
+
+// EventTypeContainsFold applies the ContainsFold predicate on the "event_type" field.
+func EventTypeContainsFold(v string) predicate.CompapiJob {
+	return predicate.CompapiJob(sql.FieldContainsFold(FieldEventType, v))
+}
+
+// WorkidIdxEQ applies the EQ predicate on the "workid_idx" field.
+func WorkidIdxEQ(v int8) predicate.CompapiJob {
+	return predicate.CompapiJob(sql.FieldEQ(FieldWorkidIdx, v))
+}
+
+// WorkidIdxNEQ applies the NEQ predicate on the "workid_idx" field.
+func WorkidIdxNEQ(v int8) predicate.CompapiJob {
+	return predicate.CompapiJob(sql.FieldNEQ(FieldWorkidIdx, v))
+}
+
+// WorkidIdxIn applies the In predicate on the "workid_idx" field.
+func WorkidIdxIn(vs ...int8) predicate.CompapiJob {
+	return predicate.CompapiJob(sql.FieldIn(FieldWorkidIdx, vs...))
+}
+
+// WorkidIdxNotIn applies the NotIn predicate on the "workid_idx" field.
+func WorkidIdxNotIn(vs ...int8) predicate.CompapiJob {
+	return predicate.CompapiJob(sql.FieldNotIn(FieldWorkidIdx, vs...))
+}
+
+// WorkidIdxGT applies the GT predicate on the "workid_idx" field.
+func WorkidIdxGT(v int8) predicate.CompapiJob {
+	return predicate.CompapiJob(sql.FieldGT(FieldWorkidIdx, v))
+}
+
+// WorkidIdxGTE applies the GTE predicate on the "workid_idx" field.
+func WorkidIdxGTE(v int8) predicate.CompapiJob {
+	return predicate.CompapiJob(sql.FieldGTE(FieldWorkidIdx, v))
+}
+
+// WorkidIdxLT applies the LT predicate on the "workid_idx" field.
+func WorkidIdxLT(v int8) predicate.CompapiJob {
+	return predicate.CompapiJob(sql.FieldLT(FieldWorkidIdx, v))
+}
+
+// WorkidIdxLTE applies the LTE predicate on the "workid_idx" field.
+func WorkidIdxLTE(v int8) predicate.CompapiJob {
+	return predicate.CompapiJob(sql.FieldLTE(FieldWorkidIdx, v))
+}
+
+// WorkidIdxIsNil applies the IsNil predicate on the "workid_idx" field.
+func WorkidIdxIsNil() predicate.CompapiJob {
+	return predicate.CompapiJob(sql.FieldIsNull(FieldWorkidIdx))
+}
+
+// WorkidIdxNotNil applies the NotNil predicate on the "workid_idx" field.
+func WorkidIdxNotNil() predicate.CompapiJob {
+	return predicate.CompapiJob(sql.FieldNotNull(FieldWorkidIdx))
+}
+
+// ChatIDEQ applies the EQ predicate on the "chat_id" field.
+func ChatIDEQ(v string) predicate.CompapiJob {
+	return predicate.CompapiJob(sql.FieldEQ(FieldChatID, v))
+}
+
+// ChatIDNEQ applies the NEQ predicate on the "chat_id" field.
+func ChatIDNEQ(v string) predicate.CompapiJob {
+	return predicate.CompapiJob(sql.FieldNEQ(FieldChatID, v))
+}
+
+// ChatIDIn applies the In predicate on the "chat_id" field.
+func ChatIDIn(vs ...string) predicate.CompapiJob {
+	return predicate.CompapiJob(sql.FieldIn(FieldChatID, vs...))
+}
+
+// ChatIDNotIn applies the NotIn predicate on the "chat_id" field.
+func ChatIDNotIn(vs ...string) predicate.CompapiJob {
+	return predicate.CompapiJob(sql.FieldNotIn(FieldChatID, vs...))
+}
+
+// ChatIDGT applies the GT predicate on the "chat_id" field.
+func ChatIDGT(v string) predicate.CompapiJob {
+	return predicate.CompapiJob(sql.FieldGT(FieldChatID, v))
+}
+
+// ChatIDGTE applies the GTE predicate on the "chat_id" field.
+func ChatIDGTE(v string) predicate.CompapiJob {
+	return predicate.CompapiJob(sql.FieldGTE(FieldChatID, v))
+}
+
+// ChatIDLT applies the LT predicate on the "chat_id" field.
+func ChatIDLT(v string) predicate.CompapiJob {
+	return predicate.CompapiJob(sql.FieldLT(FieldChatID, v))
+}
+
+// ChatIDLTE applies the LTE predicate on the "chat_id" field.
+func ChatIDLTE(v string) predicate.CompapiJob {
+	return predicate.CompapiJob(sql.FieldLTE(FieldChatID, v))
+}
+
+// ChatIDContains applies the Contains predicate on the "chat_id" field.
+func ChatIDContains(v string) predicate.CompapiJob {
+	return predicate.CompapiJob(sql.FieldContains(FieldChatID, v))
+}
+
+// ChatIDHasPrefix applies the HasPrefix predicate on the "chat_id" field.
+func ChatIDHasPrefix(v string) predicate.CompapiJob {
+	return predicate.CompapiJob(sql.FieldHasPrefix(FieldChatID, v))
+}
+
+// ChatIDHasSuffix applies the HasSuffix predicate on the "chat_id" field.
+func ChatIDHasSuffix(v string) predicate.CompapiJob {
+	return predicate.CompapiJob(sql.FieldHasSuffix(FieldChatID, v))
+}
+
+// ChatIDIsNil applies the IsNil predicate on the "chat_id" field.
+func ChatIDIsNil() predicate.CompapiJob {
+	return predicate.CompapiJob(sql.FieldIsNull(FieldChatID))
+}
+
+// ChatIDNotNil applies the NotNil predicate on the "chat_id" field.
+func ChatIDNotNil() predicate.CompapiJob {
+	return predicate.CompapiJob(sql.FieldNotNull(FieldChatID))
+}
+
+// ChatIDEqualFold applies the EqualFold predicate on the "chat_id" field.
+func ChatIDEqualFold(v string) predicate.CompapiJob {
+	return predicate.CompapiJob(sql.FieldEqualFold(FieldChatID, v))
+}
+
+// ChatIDContainsFold applies the ContainsFold predicate on the "chat_id" field.
+func ChatIDContainsFold(v string) predicate.CompapiJob {
+	return predicate.CompapiJob(sql.FieldContainsFold(FieldChatID, v))
+}
+
+// RetryCountEQ applies the EQ predicate on the "retry_count" field.
+func RetryCountEQ(v int8) predicate.CompapiJob {
+	return predicate.CompapiJob(sql.FieldEQ(FieldRetryCount, v))
+}
+
+// RetryCountNEQ applies the NEQ predicate on the "retry_count" field.
+func RetryCountNEQ(v int8) predicate.CompapiJob {
+	return predicate.CompapiJob(sql.FieldNEQ(FieldRetryCount, v))
+}
+
+// RetryCountIn applies the In predicate on the "retry_count" field.
+func RetryCountIn(vs ...int8) predicate.CompapiJob {
+	return predicate.CompapiJob(sql.FieldIn(FieldRetryCount, vs...))
+}
+
+// RetryCountNotIn applies the NotIn predicate on the "retry_count" field.
+func RetryCountNotIn(vs ...int8) predicate.CompapiJob {
+	return predicate.CompapiJob(sql.FieldNotIn(FieldRetryCount, vs...))
+}
+
+// RetryCountGT applies the GT predicate on the "retry_count" field.
+func RetryCountGT(v int8) predicate.CompapiJob {
+	return predicate.CompapiJob(sql.FieldGT(FieldRetryCount, v))
+}
+
+// RetryCountGTE applies the GTE predicate on the "retry_count" field.
+func RetryCountGTE(v int8) predicate.CompapiJob {
+	return predicate.CompapiJob(sql.FieldGTE(FieldRetryCount, v))
+}
+
+// RetryCountLT applies the LT predicate on the "retry_count" field.
+func RetryCountLT(v int8) predicate.CompapiJob {
+	return predicate.CompapiJob(sql.FieldLT(FieldRetryCount, v))
+}
+
+// RetryCountLTE applies the LTE predicate on the "retry_count" field.
+func RetryCountLTE(v int8) predicate.CompapiJob {
+	return predicate.CompapiJob(sql.FieldLTE(FieldRetryCount, v))
+}
+
+// RetryCountIsNil applies the IsNil predicate on the "retry_count" field.
+func RetryCountIsNil() predicate.CompapiJob {
+	return predicate.CompapiJob(sql.FieldIsNull(FieldRetryCount))
+}
+
+// RetryCountNotNil applies the NotNil predicate on the "retry_count" field.
+func RetryCountNotNil() predicate.CompapiJob {
+	return predicate.CompapiJob(sql.FieldNotNull(FieldRetryCount))
+}
+
+// And groups predicates with the AND operator between them.
+func And(predicates ...predicate.CompapiJob) predicate.CompapiJob {
+	return predicate.CompapiJob(sql.AndPredicates(predicates...))
+}
+
+// Or groups predicates with the OR operator between them.
+func Or(predicates ...predicate.CompapiJob) predicate.CompapiJob {
+	return predicate.CompapiJob(sql.OrPredicates(predicates...))
+}
+
+// Not applies the not operator on the given predicate.
+func Not(p predicate.CompapiJob) predicate.CompapiJob {
+	return predicate.CompapiJob(sql.NotPredicates(p))
+}

+ 1339 - 0
ent/compapijob_create.go

@@ -0,0 +1,1339 @@
+// Code generated by ent, DO NOT EDIT.
+
+package ent
+
+import (
+	"context"
+	"errors"
+	"fmt"
+	"time"
+	"wechat-api/ent/compapijob"
+	"wechat-api/ent/custom_types"
+
+	"entgo.io/ent/dialect/sql"
+	"entgo.io/ent/dialect/sql/sqlgraph"
+	"entgo.io/ent/schema/field"
+)
+
+// CompapiJobCreate is the builder for creating a CompapiJob entity.
+type CompapiJobCreate struct {
+	config
+	mutation *CompapiJobMutation
+	hooks    []Hook
+	conflict []sql.ConflictOption
+}
+
+// SetCreatedAt sets the "created_at" field.
+func (cjc *CompapiJobCreate) SetCreatedAt(t time.Time) *CompapiJobCreate {
+	cjc.mutation.SetCreatedAt(t)
+	return cjc
+}
+
+// SetNillableCreatedAt sets the "created_at" field if the given value is not nil.
+func (cjc *CompapiJobCreate) SetNillableCreatedAt(t *time.Time) *CompapiJobCreate {
+	if t != nil {
+		cjc.SetCreatedAt(*t)
+	}
+	return cjc
+}
+
+// SetUpdatedAt sets the "updated_at" field.
+func (cjc *CompapiJobCreate) SetUpdatedAt(t time.Time) *CompapiJobCreate {
+	cjc.mutation.SetUpdatedAt(t)
+	return cjc
+}
+
+// SetNillableUpdatedAt sets the "updated_at" field if the given value is not nil.
+func (cjc *CompapiJobCreate) SetNillableUpdatedAt(t *time.Time) *CompapiJobCreate {
+	if t != nil {
+		cjc.SetUpdatedAt(*t)
+	}
+	return cjc
+}
+
+// SetDistAt sets the "dist_at" field.
+func (cjc *CompapiJobCreate) SetDistAt(t time.Time) *CompapiJobCreate {
+	cjc.mutation.SetDistAt(t)
+	return cjc
+}
+
+// SetNillableDistAt sets the "dist_at" field if the given value is not nil.
+func (cjc *CompapiJobCreate) SetNillableDistAt(t *time.Time) *CompapiJobCreate {
+	if t != nil {
+		cjc.SetDistAt(*t)
+	}
+	return cjc
+}
+
+// SetDistStatus sets the "dist_status" field.
+func (cjc *CompapiJobCreate) SetDistStatus(i int8) *CompapiJobCreate {
+	cjc.mutation.SetDistStatus(i)
+	return cjc
+}
+
+// SetNillableDistStatus sets the "dist_status" field if the given value is not nil.
+func (cjc *CompapiJobCreate) SetNillableDistStatus(i *int8) *CompapiJobCreate {
+	if i != nil {
+		cjc.SetDistStatus(*i)
+	}
+	return cjc
+}
+
+// SetCallbackStatus sets the "callback_status" field.
+func (cjc *CompapiJobCreate) SetCallbackStatus(i int8) *CompapiJobCreate {
+	cjc.mutation.SetCallbackStatus(i)
+	return cjc
+}
+
+// SetNillableCallbackStatus sets the "callback_status" field if the given value is not nil.
+func (cjc *CompapiJobCreate) SetNillableCallbackStatus(i *int8) *CompapiJobCreate {
+	if i != nil {
+		cjc.SetCallbackStatus(*i)
+	}
+	return cjc
+}
+
+// SetCallbackURL sets the "callback_url" field.
+func (cjc *CompapiJobCreate) SetCallbackURL(s string) *CompapiJobCreate {
+	cjc.mutation.SetCallbackURL(s)
+	return cjc
+}
+
+// SetRequestJSON sets the "request_json" field.
+func (cjc *CompapiJobCreate) SetRequestJSON(ctd custom_types.OriginalData) *CompapiJobCreate {
+	cjc.mutation.SetRequestJSON(ctd)
+	return cjc
+}
+
+// SetAuthToken sets the "auth_token" field.
+func (cjc *CompapiJobCreate) SetAuthToken(s string) *CompapiJobCreate {
+	cjc.mutation.SetAuthToken(s)
+	return cjc
+}
+
+// SetNillableAuthToken sets the "auth_token" field if the given value is not nil.
+func (cjc *CompapiJobCreate) SetNillableAuthToken(s *string) *CompapiJobCreate {
+	if s != nil {
+		cjc.SetAuthToken(*s)
+	}
+	return cjc
+}
+
+// SetEventType sets the "event_type" field.
+func (cjc *CompapiJobCreate) SetEventType(s string) *CompapiJobCreate {
+	cjc.mutation.SetEventType(s)
+	return cjc
+}
+
+// SetNillableEventType sets the "event_type" field if the given value is not nil.
+func (cjc *CompapiJobCreate) SetNillableEventType(s *string) *CompapiJobCreate {
+	if s != nil {
+		cjc.SetEventType(*s)
+	}
+	return cjc
+}
+
+// SetWorkidIdx sets the "workid_idx" field.
+func (cjc *CompapiJobCreate) SetWorkidIdx(i int8) *CompapiJobCreate {
+	cjc.mutation.SetWorkidIdx(i)
+	return cjc
+}
+
+// SetNillableWorkidIdx sets the "workid_idx" field if the given value is not nil.
+func (cjc *CompapiJobCreate) SetNillableWorkidIdx(i *int8) *CompapiJobCreate {
+	if i != nil {
+		cjc.SetWorkidIdx(*i)
+	}
+	return cjc
+}
+
+// SetChatID sets the "chat_id" field.
+func (cjc *CompapiJobCreate) SetChatID(s string) *CompapiJobCreate {
+	cjc.mutation.SetChatID(s)
+	return cjc
+}
+
+// SetNillableChatID sets the "chat_id" field if the given value is not nil.
+func (cjc *CompapiJobCreate) SetNillableChatID(s *string) *CompapiJobCreate {
+	if s != nil {
+		cjc.SetChatID(*s)
+	}
+	return cjc
+}
+
+// SetRetryCount sets the "retry_count" field.
+func (cjc *CompapiJobCreate) SetRetryCount(i int8) *CompapiJobCreate {
+	cjc.mutation.SetRetryCount(i)
+	return cjc
+}
+
+// SetNillableRetryCount sets the "retry_count" field if the given value is not nil.
+func (cjc *CompapiJobCreate) SetNillableRetryCount(i *int8) *CompapiJobCreate {
+	if i != nil {
+		cjc.SetRetryCount(*i)
+	}
+	return cjc
+}
+
+// SetID sets the "id" field.
+func (cjc *CompapiJobCreate) SetID(u uint64) *CompapiJobCreate {
+	cjc.mutation.SetID(u)
+	return cjc
+}
+
+// Mutation returns the CompapiJobMutation object of the builder.
+func (cjc *CompapiJobCreate) Mutation() *CompapiJobMutation {
+	return cjc.mutation
+}
+
+// Save creates the CompapiJob in the database.
+func (cjc *CompapiJobCreate) Save(ctx context.Context) (*CompapiJob, error) {
+	cjc.defaults()
+	return withHooks(ctx, cjc.sqlSave, cjc.mutation, cjc.hooks)
+}
+
+// SaveX calls Save and panics if Save returns an error.
+func (cjc *CompapiJobCreate) SaveX(ctx context.Context) *CompapiJob {
+	v, err := cjc.Save(ctx)
+	if err != nil {
+		panic(err)
+	}
+	return v
+}
+
+// Exec executes the query.
+func (cjc *CompapiJobCreate) Exec(ctx context.Context) error {
+	_, err := cjc.Save(ctx)
+	return err
+}
+
+// ExecX is like Exec, but panics if an error occurs.
+func (cjc *CompapiJobCreate) ExecX(ctx context.Context) {
+	if err := cjc.Exec(ctx); err != nil {
+		panic(err)
+	}
+}
+
+// defaults sets the default values of the builder before save.
+func (cjc *CompapiJobCreate) defaults() {
+	if _, ok := cjc.mutation.CreatedAt(); !ok {
+		v := compapijob.DefaultCreatedAt()
+		cjc.mutation.SetCreatedAt(v)
+	}
+	if _, ok := cjc.mutation.UpdatedAt(); !ok {
+		v := compapijob.DefaultUpdatedAt()
+		cjc.mutation.SetUpdatedAt(v)
+	}
+	if _, ok := cjc.mutation.DistStatus(); !ok {
+		v := compapijob.DefaultDistStatus
+		cjc.mutation.SetDistStatus(v)
+	}
+	if _, ok := cjc.mutation.CallbackStatus(); !ok {
+		v := compapijob.DefaultCallbackStatus
+		cjc.mutation.SetCallbackStatus(v)
+	}
+	if _, ok := cjc.mutation.AuthToken(); !ok {
+		v := compapijob.DefaultAuthToken
+		cjc.mutation.SetAuthToken(v)
+	}
+	if _, ok := cjc.mutation.EventType(); !ok {
+		v := compapijob.DefaultEventType
+		cjc.mutation.SetEventType(v)
+	}
+	if _, ok := cjc.mutation.WorkidIdx(); !ok {
+		v := compapijob.DefaultWorkidIdx
+		cjc.mutation.SetWorkidIdx(v)
+	}
+	if _, ok := cjc.mutation.ChatID(); !ok {
+		v := compapijob.DefaultChatID
+		cjc.mutation.SetChatID(v)
+	}
+	if _, ok := cjc.mutation.RetryCount(); !ok {
+		v := compapijob.DefaultRetryCount
+		cjc.mutation.SetRetryCount(v)
+	}
+}
+
+// check runs all checks and user-defined validators on the builder.
+func (cjc *CompapiJobCreate) check() error {
+	if _, ok := cjc.mutation.CreatedAt(); !ok {
+		return &ValidationError{Name: "created_at", err: errors.New(`ent: missing required field "CompapiJob.created_at"`)}
+	}
+	if _, ok := cjc.mutation.UpdatedAt(); !ok {
+		return &ValidationError{Name: "updated_at", err: errors.New(`ent: missing required field "CompapiJob.updated_at"`)}
+	}
+	if _, ok := cjc.mutation.CallbackURL(); !ok {
+		return &ValidationError{Name: "callback_url", err: errors.New(`ent: missing required field "CompapiJob.callback_url"`)}
+	}
+	if _, ok := cjc.mutation.RequestJSON(); !ok {
+		return &ValidationError{Name: "request_json", err: errors.New(`ent: missing required field "CompapiJob.request_json"`)}
+	}
+	if _, ok := cjc.mutation.AuthToken(); !ok {
+		return &ValidationError{Name: "auth_token", err: errors.New(`ent: missing required field "CompapiJob.auth_token"`)}
+	}
+	if _, ok := cjc.mutation.EventType(); !ok {
+		return &ValidationError{Name: "event_type", err: errors.New(`ent: missing required field "CompapiJob.event_type"`)}
+	}
+	return nil
+}
+
+func (cjc *CompapiJobCreate) sqlSave(ctx context.Context) (*CompapiJob, error) {
+	if err := cjc.check(); err != nil {
+		return nil, err
+	}
+	_node, _spec := cjc.createSpec()
+	if err := sqlgraph.CreateNode(ctx, cjc.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)
+	}
+	cjc.mutation.id = &_node.ID
+	cjc.mutation.done = true
+	return _node, nil
+}
+
+func (cjc *CompapiJobCreate) createSpec() (*CompapiJob, *sqlgraph.CreateSpec) {
+	var (
+		_node = &CompapiJob{config: cjc.config}
+		_spec = sqlgraph.NewCreateSpec(compapijob.Table, sqlgraph.NewFieldSpec(compapijob.FieldID, field.TypeUint64))
+	)
+	_spec.OnConflict = cjc.conflict
+	if id, ok := cjc.mutation.ID(); ok {
+		_node.ID = id
+		_spec.ID.Value = id
+	}
+	if value, ok := cjc.mutation.CreatedAt(); ok {
+		_spec.SetField(compapijob.FieldCreatedAt, field.TypeTime, value)
+		_node.CreatedAt = value
+	}
+	if value, ok := cjc.mutation.UpdatedAt(); ok {
+		_spec.SetField(compapijob.FieldUpdatedAt, field.TypeTime, value)
+		_node.UpdatedAt = value
+	}
+	if value, ok := cjc.mutation.DistAt(); ok {
+		_spec.SetField(compapijob.FieldDistAt, field.TypeTime, value)
+		_node.DistAt = value
+	}
+	if value, ok := cjc.mutation.DistStatus(); ok {
+		_spec.SetField(compapijob.FieldDistStatus, field.TypeInt8, value)
+		_node.DistStatus = value
+	}
+	if value, ok := cjc.mutation.CallbackStatus(); ok {
+		_spec.SetField(compapijob.FieldCallbackStatus, field.TypeInt8, value)
+		_node.CallbackStatus = value
+	}
+	if value, ok := cjc.mutation.CallbackURL(); ok {
+		_spec.SetField(compapijob.FieldCallbackURL, field.TypeString, value)
+		_node.CallbackURL = value
+	}
+	if value, ok := cjc.mutation.RequestJSON(); ok {
+		_spec.SetField(compapijob.FieldRequestJSON, field.TypeJSON, value)
+		_node.RequestJSON = value
+	}
+	if value, ok := cjc.mutation.AuthToken(); ok {
+		_spec.SetField(compapijob.FieldAuthToken, field.TypeString, value)
+		_node.AuthToken = value
+	}
+	if value, ok := cjc.mutation.EventType(); ok {
+		_spec.SetField(compapijob.FieldEventType, field.TypeString, value)
+		_node.EventType = value
+	}
+	if value, ok := cjc.mutation.WorkidIdx(); ok {
+		_spec.SetField(compapijob.FieldWorkidIdx, field.TypeInt8, value)
+		_node.WorkidIdx = value
+	}
+	if value, ok := cjc.mutation.ChatID(); ok {
+		_spec.SetField(compapijob.FieldChatID, field.TypeString, value)
+		_node.ChatID = value
+	}
+	if value, ok := cjc.mutation.RetryCount(); ok {
+		_spec.SetField(compapijob.FieldRetryCount, field.TypeInt8, value)
+		_node.RetryCount = value
+	}
+	return _node, _spec
+}
+
+// OnConflict allows configuring the `ON CONFLICT` / `ON DUPLICATE KEY` clause
+// of the `INSERT` statement. For example:
+//
+//	client.CompapiJob.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.CompapiJobUpsert) {
+//			SetCreatedAt(v+v).
+//		}).
+//		Exec(ctx)
+func (cjc *CompapiJobCreate) OnConflict(opts ...sql.ConflictOption) *CompapiJobUpsertOne {
+	cjc.conflict = opts
+	return &CompapiJobUpsertOne{
+		create: cjc,
+	}
+}
+
+// OnConflictColumns calls `OnConflict` and configures the columns
+// as conflict target. Using this option is equivalent to using:
+//
+//	client.CompapiJob.Create().
+//		OnConflict(sql.ConflictColumns(columns...)).
+//		Exec(ctx)
+func (cjc *CompapiJobCreate) OnConflictColumns(columns ...string) *CompapiJobUpsertOne {
+	cjc.conflict = append(cjc.conflict, sql.ConflictColumns(columns...))
+	return &CompapiJobUpsertOne{
+		create: cjc,
+	}
+}
+
+type (
+	// CompapiJobUpsertOne is the builder for "upsert"-ing
+	//  one CompapiJob node.
+	CompapiJobUpsertOne struct {
+		create *CompapiJobCreate
+	}
+
+	// CompapiJobUpsert is the "OnConflict" setter.
+	CompapiJobUpsert struct {
+		*sql.UpdateSet
+	}
+)
+
+// SetUpdatedAt sets the "updated_at" field.
+func (u *CompapiJobUpsert) SetUpdatedAt(v time.Time) *CompapiJobUpsert {
+	u.Set(compapijob.FieldUpdatedAt, v)
+	return u
+}
+
+// UpdateUpdatedAt sets the "updated_at" field to the value that was provided on create.
+func (u *CompapiJobUpsert) UpdateUpdatedAt() *CompapiJobUpsert {
+	u.SetExcluded(compapijob.FieldUpdatedAt)
+	return u
+}
+
+// SetDistAt sets the "dist_at" field.
+func (u *CompapiJobUpsert) SetDistAt(v time.Time) *CompapiJobUpsert {
+	u.Set(compapijob.FieldDistAt, v)
+	return u
+}
+
+// UpdateDistAt sets the "dist_at" field to the value that was provided on create.
+func (u *CompapiJobUpsert) UpdateDistAt() *CompapiJobUpsert {
+	u.SetExcluded(compapijob.FieldDistAt)
+	return u
+}
+
+// ClearDistAt clears the value of the "dist_at" field.
+func (u *CompapiJobUpsert) ClearDistAt() *CompapiJobUpsert {
+	u.SetNull(compapijob.FieldDistAt)
+	return u
+}
+
+// SetDistStatus sets the "dist_status" field.
+func (u *CompapiJobUpsert) SetDistStatus(v int8) *CompapiJobUpsert {
+	u.Set(compapijob.FieldDistStatus, v)
+	return u
+}
+
+// UpdateDistStatus sets the "dist_status" field to the value that was provided on create.
+func (u *CompapiJobUpsert) UpdateDistStatus() *CompapiJobUpsert {
+	u.SetExcluded(compapijob.FieldDistStatus)
+	return u
+}
+
+// AddDistStatus adds v to the "dist_status" field.
+func (u *CompapiJobUpsert) AddDistStatus(v int8) *CompapiJobUpsert {
+	u.Add(compapijob.FieldDistStatus, v)
+	return u
+}
+
+// ClearDistStatus clears the value of the "dist_status" field.
+func (u *CompapiJobUpsert) ClearDistStatus() *CompapiJobUpsert {
+	u.SetNull(compapijob.FieldDistStatus)
+	return u
+}
+
+// SetCallbackStatus sets the "callback_status" field.
+func (u *CompapiJobUpsert) SetCallbackStatus(v int8) *CompapiJobUpsert {
+	u.Set(compapijob.FieldCallbackStatus, v)
+	return u
+}
+
+// UpdateCallbackStatus sets the "callback_status" field to the value that was provided on create.
+func (u *CompapiJobUpsert) UpdateCallbackStatus() *CompapiJobUpsert {
+	u.SetExcluded(compapijob.FieldCallbackStatus)
+	return u
+}
+
+// AddCallbackStatus adds v to the "callback_status" field.
+func (u *CompapiJobUpsert) AddCallbackStatus(v int8) *CompapiJobUpsert {
+	u.Add(compapijob.FieldCallbackStatus, v)
+	return u
+}
+
+// ClearCallbackStatus clears the value of the "callback_status" field.
+func (u *CompapiJobUpsert) ClearCallbackStatus() *CompapiJobUpsert {
+	u.SetNull(compapijob.FieldCallbackStatus)
+	return u
+}
+
+// SetCallbackURL sets the "callback_url" field.
+func (u *CompapiJobUpsert) SetCallbackURL(v string) *CompapiJobUpsert {
+	u.Set(compapijob.FieldCallbackURL, v)
+	return u
+}
+
+// UpdateCallbackURL sets the "callback_url" field to the value that was provided on create.
+func (u *CompapiJobUpsert) UpdateCallbackURL() *CompapiJobUpsert {
+	u.SetExcluded(compapijob.FieldCallbackURL)
+	return u
+}
+
+// SetRequestJSON sets the "request_json" field.
+func (u *CompapiJobUpsert) SetRequestJSON(v custom_types.OriginalData) *CompapiJobUpsert {
+	u.Set(compapijob.FieldRequestJSON, v)
+	return u
+}
+
+// UpdateRequestJSON sets the "request_json" field to the value that was provided on create.
+func (u *CompapiJobUpsert) UpdateRequestJSON() *CompapiJobUpsert {
+	u.SetExcluded(compapijob.FieldRequestJSON)
+	return u
+}
+
+// SetAuthToken sets the "auth_token" field.
+func (u *CompapiJobUpsert) SetAuthToken(v string) *CompapiJobUpsert {
+	u.Set(compapijob.FieldAuthToken, v)
+	return u
+}
+
+// UpdateAuthToken sets the "auth_token" field to the value that was provided on create.
+func (u *CompapiJobUpsert) UpdateAuthToken() *CompapiJobUpsert {
+	u.SetExcluded(compapijob.FieldAuthToken)
+	return u
+}
+
+// SetEventType sets the "event_type" field.
+func (u *CompapiJobUpsert) SetEventType(v string) *CompapiJobUpsert {
+	u.Set(compapijob.FieldEventType, v)
+	return u
+}
+
+// UpdateEventType sets the "event_type" field to the value that was provided on create.
+func (u *CompapiJobUpsert) UpdateEventType() *CompapiJobUpsert {
+	u.SetExcluded(compapijob.FieldEventType)
+	return u
+}
+
+// SetWorkidIdx sets the "workid_idx" field.
+func (u *CompapiJobUpsert) SetWorkidIdx(v int8) *CompapiJobUpsert {
+	u.Set(compapijob.FieldWorkidIdx, v)
+	return u
+}
+
+// UpdateWorkidIdx sets the "workid_idx" field to the value that was provided on create.
+func (u *CompapiJobUpsert) UpdateWorkidIdx() *CompapiJobUpsert {
+	u.SetExcluded(compapijob.FieldWorkidIdx)
+	return u
+}
+
+// AddWorkidIdx adds v to the "workid_idx" field.
+func (u *CompapiJobUpsert) AddWorkidIdx(v int8) *CompapiJobUpsert {
+	u.Add(compapijob.FieldWorkidIdx, v)
+	return u
+}
+
+// ClearWorkidIdx clears the value of the "workid_idx" field.
+func (u *CompapiJobUpsert) ClearWorkidIdx() *CompapiJobUpsert {
+	u.SetNull(compapijob.FieldWorkidIdx)
+	return u
+}
+
+// SetChatID sets the "chat_id" field.
+func (u *CompapiJobUpsert) SetChatID(v string) *CompapiJobUpsert {
+	u.Set(compapijob.FieldChatID, v)
+	return u
+}
+
+// UpdateChatID sets the "chat_id" field to the value that was provided on create.
+func (u *CompapiJobUpsert) UpdateChatID() *CompapiJobUpsert {
+	u.SetExcluded(compapijob.FieldChatID)
+	return u
+}
+
+// ClearChatID clears the value of the "chat_id" field.
+func (u *CompapiJobUpsert) ClearChatID() *CompapiJobUpsert {
+	u.SetNull(compapijob.FieldChatID)
+	return u
+}
+
+// SetRetryCount sets the "retry_count" field.
+func (u *CompapiJobUpsert) SetRetryCount(v int8) *CompapiJobUpsert {
+	u.Set(compapijob.FieldRetryCount, v)
+	return u
+}
+
+// UpdateRetryCount sets the "retry_count" field to the value that was provided on create.
+func (u *CompapiJobUpsert) UpdateRetryCount() *CompapiJobUpsert {
+	u.SetExcluded(compapijob.FieldRetryCount)
+	return u
+}
+
+// AddRetryCount adds v to the "retry_count" field.
+func (u *CompapiJobUpsert) AddRetryCount(v int8) *CompapiJobUpsert {
+	u.Add(compapijob.FieldRetryCount, v)
+	return u
+}
+
+// ClearRetryCount clears the value of the "retry_count" field.
+func (u *CompapiJobUpsert) ClearRetryCount() *CompapiJobUpsert {
+	u.SetNull(compapijob.FieldRetryCount)
+	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.CompapiJob.Create().
+//		OnConflict(
+//			sql.ResolveWithNewValues(),
+//			sql.ResolveWith(func(u *sql.UpdateSet) {
+//				u.SetIgnore(compapijob.FieldID)
+//			}),
+//		).
+//		Exec(ctx)
+func (u *CompapiJobUpsertOne) UpdateNewValues() *CompapiJobUpsertOne {
+	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(compapijob.FieldID)
+		}
+		if _, exists := u.create.mutation.CreatedAt(); exists {
+			s.SetIgnore(compapijob.FieldCreatedAt)
+		}
+	}))
+	return u
+}
+
+// Ignore sets each column to itself in case of conflict.
+// Using this option is equivalent to using:
+//
+//	client.CompapiJob.Create().
+//	    OnConflict(sql.ResolveWithIgnore()).
+//	    Exec(ctx)
+func (u *CompapiJobUpsertOne) Ignore() *CompapiJobUpsertOne {
+	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 *CompapiJobUpsertOne) DoNothing() *CompapiJobUpsertOne {
+	u.create.conflict = append(u.create.conflict, sql.DoNothing())
+	return u
+}
+
+// Update allows overriding fields `UPDATE` values. See the CompapiJobCreate.OnConflict
+// documentation for more info.
+func (u *CompapiJobUpsertOne) Update(set func(*CompapiJobUpsert)) *CompapiJobUpsertOne {
+	u.create.conflict = append(u.create.conflict, sql.ResolveWith(func(update *sql.UpdateSet) {
+		set(&CompapiJobUpsert{UpdateSet: update})
+	}))
+	return u
+}
+
+// SetUpdatedAt sets the "updated_at" field.
+func (u *CompapiJobUpsertOne) SetUpdatedAt(v time.Time) *CompapiJobUpsertOne {
+	return u.Update(func(s *CompapiJobUpsert) {
+		s.SetUpdatedAt(v)
+	})
+}
+
+// UpdateUpdatedAt sets the "updated_at" field to the value that was provided on create.
+func (u *CompapiJobUpsertOne) UpdateUpdatedAt() *CompapiJobUpsertOne {
+	return u.Update(func(s *CompapiJobUpsert) {
+		s.UpdateUpdatedAt()
+	})
+}
+
+// SetDistAt sets the "dist_at" field.
+func (u *CompapiJobUpsertOne) SetDistAt(v time.Time) *CompapiJobUpsertOne {
+	return u.Update(func(s *CompapiJobUpsert) {
+		s.SetDistAt(v)
+	})
+}
+
+// UpdateDistAt sets the "dist_at" field to the value that was provided on create.
+func (u *CompapiJobUpsertOne) UpdateDistAt() *CompapiJobUpsertOne {
+	return u.Update(func(s *CompapiJobUpsert) {
+		s.UpdateDistAt()
+	})
+}
+
+// ClearDistAt clears the value of the "dist_at" field.
+func (u *CompapiJobUpsertOne) ClearDistAt() *CompapiJobUpsertOne {
+	return u.Update(func(s *CompapiJobUpsert) {
+		s.ClearDistAt()
+	})
+}
+
+// SetDistStatus sets the "dist_status" field.
+func (u *CompapiJobUpsertOne) SetDistStatus(v int8) *CompapiJobUpsertOne {
+	return u.Update(func(s *CompapiJobUpsert) {
+		s.SetDistStatus(v)
+	})
+}
+
+// AddDistStatus adds v to the "dist_status" field.
+func (u *CompapiJobUpsertOne) AddDistStatus(v int8) *CompapiJobUpsertOne {
+	return u.Update(func(s *CompapiJobUpsert) {
+		s.AddDistStatus(v)
+	})
+}
+
+// UpdateDistStatus sets the "dist_status" field to the value that was provided on create.
+func (u *CompapiJobUpsertOne) UpdateDistStatus() *CompapiJobUpsertOne {
+	return u.Update(func(s *CompapiJobUpsert) {
+		s.UpdateDistStatus()
+	})
+}
+
+// ClearDistStatus clears the value of the "dist_status" field.
+func (u *CompapiJobUpsertOne) ClearDistStatus() *CompapiJobUpsertOne {
+	return u.Update(func(s *CompapiJobUpsert) {
+		s.ClearDistStatus()
+	})
+}
+
+// SetCallbackStatus sets the "callback_status" field.
+func (u *CompapiJobUpsertOne) SetCallbackStatus(v int8) *CompapiJobUpsertOne {
+	return u.Update(func(s *CompapiJobUpsert) {
+		s.SetCallbackStatus(v)
+	})
+}
+
+// AddCallbackStatus adds v to the "callback_status" field.
+func (u *CompapiJobUpsertOne) AddCallbackStatus(v int8) *CompapiJobUpsertOne {
+	return u.Update(func(s *CompapiJobUpsert) {
+		s.AddCallbackStatus(v)
+	})
+}
+
+// UpdateCallbackStatus sets the "callback_status" field to the value that was provided on create.
+func (u *CompapiJobUpsertOne) UpdateCallbackStatus() *CompapiJobUpsertOne {
+	return u.Update(func(s *CompapiJobUpsert) {
+		s.UpdateCallbackStatus()
+	})
+}
+
+// ClearCallbackStatus clears the value of the "callback_status" field.
+func (u *CompapiJobUpsertOne) ClearCallbackStatus() *CompapiJobUpsertOne {
+	return u.Update(func(s *CompapiJobUpsert) {
+		s.ClearCallbackStatus()
+	})
+}
+
+// SetCallbackURL sets the "callback_url" field.
+func (u *CompapiJobUpsertOne) SetCallbackURL(v string) *CompapiJobUpsertOne {
+	return u.Update(func(s *CompapiJobUpsert) {
+		s.SetCallbackURL(v)
+	})
+}
+
+// UpdateCallbackURL sets the "callback_url" field to the value that was provided on create.
+func (u *CompapiJobUpsertOne) UpdateCallbackURL() *CompapiJobUpsertOne {
+	return u.Update(func(s *CompapiJobUpsert) {
+		s.UpdateCallbackURL()
+	})
+}
+
+// SetRequestJSON sets the "request_json" field.
+func (u *CompapiJobUpsertOne) SetRequestJSON(v custom_types.OriginalData) *CompapiJobUpsertOne {
+	return u.Update(func(s *CompapiJobUpsert) {
+		s.SetRequestJSON(v)
+	})
+}
+
+// UpdateRequestJSON sets the "request_json" field to the value that was provided on create.
+func (u *CompapiJobUpsertOne) UpdateRequestJSON() *CompapiJobUpsertOne {
+	return u.Update(func(s *CompapiJobUpsert) {
+		s.UpdateRequestJSON()
+	})
+}
+
+// SetAuthToken sets the "auth_token" field.
+func (u *CompapiJobUpsertOne) SetAuthToken(v string) *CompapiJobUpsertOne {
+	return u.Update(func(s *CompapiJobUpsert) {
+		s.SetAuthToken(v)
+	})
+}
+
+// UpdateAuthToken sets the "auth_token" field to the value that was provided on create.
+func (u *CompapiJobUpsertOne) UpdateAuthToken() *CompapiJobUpsertOne {
+	return u.Update(func(s *CompapiJobUpsert) {
+		s.UpdateAuthToken()
+	})
+}
+
+// SetEventType sets the "event_type" field.
+func (u *CompapiJobUpsertOne) SetEventType(v string) *CompapiJobUpsertOne {
+	return u.Update(func(s *CompapiJobUpsert) {
+		s.SetEventType(v)
+	})
+}
+
+// UpdateEventType sets the "event_type" field to the value that was provided on create.
+func (u *CompapiJobUpsertOne) UpdateEventType() *CompapiJobUpsertOne {
+	return u.Update(func(s *CompapiJobUpsert) {
+		s.UpdateEventType()
+	})
+}
+
+// SetWorkidIdx sets the "workid_idx" field.
+func (u *CompapiJobUpsertOne) SetWorkidIdx(v int8) *CompapiJobUpsertOne {
+	return u.Update(func(s *CompapiJobUpsert) {
+		s.SetWorkidIdx(v)
+	})
+}
+
+// AddWorkidIdx adds v to the "workid_idx" field.
+func (u *CompapiJobUpsertOne) AddWorkidIdx(v int8) *CompapiJobUpsertOne {
+	return u.Update(func(s *CompapiJobUpsert) {
+		s.AddWorkidIdx(v)
+	})
+}
+
+// UpdateWorkidIdx sets the "workid_idx" field to the value that was provided on create.
+func (u *CompapiJobUpsertOne) UpdateWorkidIdx() *CompapiJobUpsertOne {
+	return u.Update(func(s *CompapiJobUpsert) {
+		s.UpdateWorkidIdx()
+	})
+}
+
+// ClearWorkidIdx clears the value of the "workid_idx" field.
+func (u *CompapiJobUpsertOne) ClearWorkidIdx() *CompapiJobUpsertOne {
+	return u.Update(func(s *CompapiJobUpsert) {
+		s.ClearWorkidIdx()
+	})
+}
+
+// SetChatID sets the "chat_id" field.
+func (u *CompapiJobUpsertOne) SetChatID(v string) *CompapiJobUpsertOne {
+	return u.Update(func(s *CompapiJobUpsert) {
+		s.SetChatID(v)
+	})
+}
+
+// UpdateChatID sets the "chat_id" field to the value that was provided on create.
+func (u *CompapiJobUpsertOne) UpdateChatID() *CompapiJobUpsertOne {
+	return u.Update(func(s *CompapiJobUpsert) {
+		s.UpdateChatID()
+	})
+}
+
+// ClearChatID clears the value of the "chat_id" field.
+func (u *CompapiJobUpsertOne) ClearChatID() *CompapiJobUpsertOne {
+	return u.Update(func(s *CompapiJobUpsert) {
+		s.ClearChatID()
+	})
+}
+
+// SetRetryCount sets the "retry_count" field.
+func (u *CompapiJobUpsertOne) SetRetryCount(v int8) *CompapiJobUpsertOne {
+	return u.Update(func(s *CompapiJobUpsert) {
+		s.SetRetryCount(v)
+	})
+}
+
+// AddRetryCount adds v to the "retry_count" field.
+func (u *CompapiJobUpsertOne) AddRetryCount(v int8) *CompapiJobUpsertOne {
+	return u.Update(func(s *CompapiJobUpsert) {
+		s.AddRetryCount(v)
+	})
+}
+
+// UpdateRetryCount sets the "retry_count" field to the value that was provided on create.
+func (u *CompapiJobUpsertOne) UpdateRetryCount() *CompapiJobUpsertOne {
+	return u.Update(func(s *CompapiJobUpsert) {
+		s.UpdateRetryCount()
+	})
+}
+
+// ClearRetryCount clears the value of the "retry_count" field.
+func (u *CompapiJobUpsertOne) ClearRetryCount() *CompapiJobUpsertOne {
+	return u.Update(func(s *CompapiJobUpsert) {
+		s.ClearRetryCount()
+	})
+}
+
+// Exec executes the query.
+func (u *CompapiJobUpsertOne) Exec(ctx context.Context) error {
+	if len(u.create.conflict) == 0 {
+		return errors.New("ent: missing options for CompapiJobCreate.OnConflict")
+	}
+	return u.create.Exec(ctx)
+}
+
+// ExecX is like Exec, but panics if an error occurs.
+func (u *CompapiJobUpsertOne) 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 *CompapiJobUpsertOne) 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 *CompapiJobUpsertOne) IDX(ctx context.Context) uint64 {
+	id, err := u.ID(ctx)
+	if err != nil {
+		panic(err)
+	}
+	return id
+}
+
+// CompapiJobCreateBulk is the builder for creating many CompapiJob entities in bulk.
+type CompapiJobCreateBulk struct {
+	config
+	err      error
+	builders []*CompapiJobCreate
+	conflict []sql.ConflictOption
+}
+
+// Save creates the CompapiJob entities in the database.
+func (cjcb *CompapiJobCreateBulk) Save(ctx context.Context) ([]*CompapiJob, error) {
+	if cjcb.err != nil {
+		return nil, cjcb.err
+	}
+	specs := make([]*sqlgraph.CreateSpec, len(cjcb.builders))
+	nodes := make([]*CompapiJob, len(cjcb.builders))
+	mutators := make([]Mutator, len(cjcb.builders))
+	for i := range cjcb.builders {
+		func(i int, root context.Context) {
+			builder := cjcb.builders[i]
+			builder.defaults()
+			var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) {
+				mutation, ok := m.(*CompapiJobMutation)
+				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, cjcb.builders[i+1].mutation)
+				} else {
+					spec := &sqlgraph.BatchCreateSpec{Nodes: specs}
+					spec.OnConflict = cjcb.conflict
+					// Invoke the actual operation on the latest mutation in the chain.
+					if err = sqlgraph.BatchCreate(ctx, cjcb.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, cjcb.builders[0].mutation); err != nil {
+			return nil, err
+		}
+	}
+	return nodes, nil
+}
+
+// SaveX is like Save, but panics if an error occurs.
+func (cjcb *CompapiJobCreateBulk) SaveX(ctx context.Context) []*CompapiJob {
+	v, err := cjcb.Save(ctx)
+	if err != nil {
+		panic(err)
+	}
+	return v
+}
+
+// Exec executes the query.
+func (cjcb *CompapiJobCreateBulk) Exec(ctx context.Context) error {
+	_, err := cjcb.Save(ctx)
+	return err
+}
+
+// ExecX is like Exec, but panics if an error occurs.
+func (cjcb *CompapiJobCreateBulk) ExecX(ctx context.Context) {
+	if err := cjcb.Exec(ctx); err != nil {
+		panic(err)
+	}
+}
+
+// OnConflict allows configuring the `ON CONFLICT` / `ON DUPLICATE KEY` clause
+// of the `INSERT` statement. For example:
+//
+//	client.CompapiJob.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.CompapiJobUpsert) {
+//			SetCreatedAt(v+v).
+//		}).
+//		Exec(ctx)
+func (cjcb *CompapiJobCreateBulk) OnConflict(opts ...sql.ConflictOption) *CompapiJobUpsertBulk {
+	cjcb.conflict = opts
+	return &CompapiJobUpsertBulk{
+		create: cjcb,
+	}
+}
+
+// OnConflictColumns calls `OnConflict` and configures the columns
+// as conflict target. Using this option is equivalent to using:
+//
+//	client.CompapiJob.Create().
+//		OnConflict(sql.ConflictColumns(columns...)).
+//		Exec(ctx)
+func (cjcb *CompapiJobCreateBulk) OnConflictColumns(columns ...string) *CompapiJobUpsertBulk {
+	cjcb.conflict = append(cjcb.conflict, sql.ConflictColumns(columns...))
+	return &CompapiJobUpsertBulk{
+		create: cjcb,
+	}
+}
+
+// CompapiJobUpsertBulk is the builder for "upsert"-ing
+// a bulk of CompapiJob nodes.
+type CompapiJobUpsertBulk struct {
+	create *CompapiJobCreateBulk
+}
+
+// UpdateNewValues updates the mutable fields using the new values that
+// were set on create. Using this option is equivalent to using:
+//
+//	client.CompapiJob.Create().
+//		OnConflict(
+//			sql.ResolveWithNewValues(),
+//			sql.ResolveWith(func(u *sql.UpdateSet) {
+//				u.SetIgnore(compapijob.FieldID)
+//			}),
+//		).
+//		Exec(ctx)
+func (u *CompapiJobUpsertBulk) UpdateNewValues() *CompapiJobUpsertBulk {
+	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(compapijob.FieldID)
+			}
+			if _, exists := b.mutation.CreatedAt(); exists {
+				s.SetIgnore(compapijob.FieldCreatedAt)
+			}
+		}
+	}))
+	return u
+}
+
+// Ignore sets each column to itself in case of conflict.
+// Using this option is equivalent to using:
+//
+//	client.CompapiJob.Create().
+//		OnConflict(sql.ResolveWithIgnore()).
+//		Exec(ctx)
+func (u *CompapiJobUpsertBulk) Ignore() *CompapiJobUpsertBulk {
+	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 *CompapiJobUpsertBulk) DoNothing() *CompapiJobUpsertBulk {
+	u.create.conflict = append(u.create.conflict, sql.DoNothing())
+	return u
+}
+
+// Update allows overriding fields `UPDATE` values. See the CompapiJobCreateBulk.OnConflict
+// documentation for more info.
+func (u *CompapiJobUpsertBulk) Update(set func(*CompapiJobUpsert)) *CompapiJobUpsertBulk {
+	u.create.conflict = append(u.create.conflict, sql.ResolveWith(func(update *sql.UpdateSet) {
+		set(&CompapiJobUpsert{UpdateSet: update})
+	}))
+	return u
+}
+
+// SetUpdatedAt sets the "updated_at" field.
+func (u *CompapiJobUpsertBulk) SetUpdatedAt(v time.Time) *CompapiJobUpsertBulk {
+	return u.Update(func(s *CompapiJobUpsert) {
+		s.SetUpdatedAt(v)
+	})
+}
+
+// UpdateUpdatedAt sets the "updated_at" field to the value that was provided on create.
+func (u *CompapiJobUpsertBulk) UpdateUpdatedAt() *CompapiJobUpsertBulk {
+	return u.Update(func(s *CompapiJobUpsert) {
+		s.UpdateUpdatedAt()
+	})
+}
+
+// SetDistAt sets the "dist_at" field.
+func (u *CompapiJobUpsertBulk) SetDistAt(v time.Time) *CompapiJobUpsertBulk {
+	return u.Update(func(s *CompapiJobUpsert) {
+		s.SetDistAt(v)
+	})
+}
+
+// UpdateDistAt sets the "dist_at" field to the value that was provided on create.
+func (u *CompapiJobUpsertBulk) UpdateDistAt() *CompapiJobUpsertBulk {
+	return u.Update(func(s *CompapiJobUpsert) {
+		s.UpdateDistAt()
+	})
+}
+
+// ClearDistAt clears the value of the "dist_at" field.
+func (u *CompapiJobUpsertBulk) ClearDistAt() *CompapiJobUpsertBulk {
+	return u.Update(func(s *CompapiJobUpsert) {
+		s.ClearDistAt()
+	})
+}
+
+// SetDistStatus sets the "dist_status" field.
+func (u *CompapiJobUpsertBulk) SetDistStatus(v int8) *CompapiJobUpsertBulk {
+	return u.Update(func(s *CompapiJobUpsert) {
+		s.SetDistStatus(v)
+	})
+}
+
+// AddDistStatus adds v to the "dist_status" field.
+func (u *CompapiJobUpsertBulk) AddDistStatus(v int8) *CompapiJobUpsertBulk {
+	return u.Update(func(s *CompapiJobUpsert) {
+		s.AddDistStatus(v)
+	})
+}
+
+// UpdateDistStatus sets the "dist_status" field to the value that was provided on create.
+func (u *CompapiJobUpsertBulk) UpdateDistStatus() *CompapiJobUpsertBulk {
+	return u.Update(func(s *CompapiJobUpsert) {
+		s.UpdateDistStatus()
+	})
+}
+
+// ClearDistStatus clears the value of the "dist_status" field.
+func (u *CompapiJobUpsertBulk) ClearDistStatus() *CompapiJobUpsertBulk {
+	return u.Update(func(s *CompapiJobUpsert) {
+		s.ClearDistStatus()
+	})
+}
+
+// SetCallbackStatus sets the "callback_status" field.
+func (u *CompapiJobUpsertBulk) SetCallbackStatus(v int8) *CompapiJobUpsertBulk {
+	return u.Update(func(s *CompapiJobUpsert) {
+		s.SetCallbackStatus(v)
+	})
+}
+
+// AddCallbackStatus adds v to the "callback_status" field.
+func (u *CompapiJobUpsertBulk) AddCallbackStatus(v int8) *CompapiJobUpsertBulk {
+	return u.Update(func(s *CompapiJobUpsert) {
+		s.AddCallbackStatus(v)
+	})
+}
+
+// UpdateCallbackStatus sets the "callback_status" field to the value that was provided on create.
+func (u *CompapiJobUpsertBulk) UpdateCallbackStatus() *CompapiJobUpsertBulk {
+	return u.Update(func(s *CompapiJobUpsert) {
+		s.UpdateCallbackStatus()
+	})
+}
+
+// ClearCallbackStatus clears the value of the "callback_status" field.
+func (u *CompapiJobUpsertBulk) ClearCallbackStatus() *CompapiJobUpsertBulk {
+	return u.Update(func(s *CompapiJobUpsert) {
+		s.ClearCallbackStatus()
+	})
+}
+
+// SetCallbackURL sets the "callback_url" field.
+func (u *CompapiJobUpsertBulk) SetCallbackURL(v string) *CompapiJobUpsertBulk {
+	return u.Update(func(s *CompapiJobUpsert) {
+		s.SetCallbackURL(v)
+	})
+}
+
+// UpdateCallbackURL sets the "callback_url" field to the value that was provided on create.
+func (u *CompapiJobUpsertBulk) UpdateCallbackURL() *CompapiJobUpsertBulk {
+	return u.Update(func(s *CompapiJobUpsert) {
+		s.UpdateCallbackURL()
+	})
+}
+
+// SetRequestJSON sets the "request_json" field.
+func (u *CompapiJobUpsertBulk) SetRequestJSON(v custom_types.OriginalData) *CompapiJobUpsertBulk {
+	return u.Update(func(s *CompapiJobUpsert) {
+		s.SetRequestJSON(v)
+	})
+}
+
+// UpdateRequestJSON sets the "request_json" field to the value that was provided on create.
+func (u *CompapiJobUpsertBulk) UpdateRequestJSON() *CompapiJobUpsertBulk {
+	return u.Update(func(s *CompapiJobUpsert) {
+		s.UpdateRequestJSON()
+	})
+}
+
+// SetAuthToken sets the "auth_token" field.
+func (u *CompapiJobUpsertBulk) SetAuthToken(v string) *CompapiJobUpsertBulk {
+	return u.Update(func(s *CompapiJobUpsert) {
+		s.SetAuthToken(v)
+	})
+}
+
+// UpdateAuthToken sets the "auth_token" field to the value that was provided on create.
+func (u *CompapiJobUpsertBulk) UpdateAuthToken() *CompapiJobUpsertBulk {
+	return u.Update(func(s *CompapiJobUpsert) {
+		s.UpdateAuthToken()
+	})
+}
+
+// SetEventType sets the "event_type" field.
+func (u *CompapiJobUpsertBulk) SetEventType(v string) *CompapiJobUpsertBulk {
+	return u.Update(func(s *CompapiJobUpsert) {
+		s.SetEventType(v)
+	})
+}
+
+// UpdateEventType sets the "event_type" field to the value that was provided on create.
+func (u *CompapiJobUpsertBulk) UpdateEventType() *CompapiJobUpsertBulk {
+	return u.Update(func(s *CompapiJobUpsert) {
+		s.UpdateEventType()
+	})
+}
+
+// SetWorkidIdx sets the "workid_idx" field.
+func (u *CompapiJobUpsertBulk) SetWorkidIdx(v int8) *CompapiJobUpsertBulk {
+	return u.Update(func(s *CompapiJobUpsert) {
+		s.SetWorkidIdx(v)
+	})
+}
+
+// AddWorkidIdx adds v to the "workid_idx" field.
+func (u *CompapiJobUpsertBulk) AddWorkidIdx(v int8) *CompapiJobUpsertBulk {
+	return u.Update(func(s *CompapiJobUpsert) {
+		s.AddWorkidIdx(v)
+	})
+}
+
+// UpdateWorkidIdx sets the "workid_idx" field to the value that was provided on create.
+func (u *CompapiJobUpsertBulk) UpdateWorkidIdx() *CompapiJobUpsertBulk {
+	return u.Update(func(s *CompapiJobUpsert) {
+		s.UpdateWorkidIdx()
+	})
+}
+
+// ClearWorkidIdx clears the value of the "workid_idx" field.
+func (u *CompapiJobUpsertBulk) ClearWorkidIdx() *CompapiJobUpsertBulk {
+	return u.Update(func(s *CompapiJobUpsert) {
+		s.ClearWorkidIdx()
+	})
+}
+
+// SetChatID sets the "chat_id" field.
+func (u *CompapiJobUpsertBulk) SetChatID(v string) *CompapiJobUpsertBulk {
+	return u.Update(func(s *CompapiJobUpsert) {
+		s.SetChatID(v)
+	})
+}
+
+// UpdateChatID sets the "chat_id" field to the value that was provided on create.
+func (u *CompapiJobUpsertBulk) UpdateChatID() *CompapiJobUpsertBulk {
+	return u.Update(func(s *CompapiJobUpsert) {
+		s.UpdateChatID()
+	})
+}
+
+// ClearChatID clears the value of the "chat_id" field.
+func (u *CompapiJobUpsertBulk) ClearChatID() *CompapiJobUpsertBulk {
+	return u.Update(func(s *CompapiJobUpsert) {
+		s.ClearChatID()
+	})
+}
+
+// SetRetryCount sets the "retry_count" field.
+func (u *CompapiJobUpsertBulk) SetRetryCount(v int8) *CompapiJobUpsertBulk {
+	return u.Update(func(s *CompapiJobUpsert) {
+		s.SetRetryCount(v)
+	})
+}
+
+// AddRetryCount adds v to the "retry_count" field.
+func (u *CompapiJobUpsertBulk) AddRetryCount(v int8) *CompapiJobUpsertBulk {
+	return u.Update(func(s *CompapiJobUpsert) {
+		s.AddRetryCount(v)
+	})
+}
+
+// UpdateRetryCount sets the "retry_count" field to the value that was provided on create.
+func (u *CompapiJobUpsertBulk) UpdateRetryCount() *CompapiJobUpsertBulk {
+	return u.Update(func(s *CompapiJobUpsert) {
+		s.UpdateRetryCount()
+	})
+}
+
+// ClearRetryCount clears the value of the "retry_count" field.
+func (u *CompapiJobUpsertBulk) ClearRetryCount() *CompapiJobUpsertBulk {
+	return u.Update(func(s *CompapiJobUpsert) {
+		s.ClearRetryCount()
+	})
+}
+
+// Exec executes the query.
+func (u *CompapiJobUpsertBulk) 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 CompapiJobCreateBulk instead", i)
+		}
+	}
+	if len(u.create.conflict) == 0 {
+		return errors.New("ent: missing options for CompapiJobCreateBulk.OnConflict")
+	}
+	return u.create.Exec(ctx)
+}
+
+// ExecX is like Exec, but panics if an error occurs.
+func (u *CompapiJobUpsertBulk) ExecX(ctx context.Context) {
+	if err := u.create.Exec(ctx); err != nil {
+		panic(err)
+	}
+}

+ 88 - 0
ent/compapijob_delete.go

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

+ 526 - 0
ent/compapijob_query.go

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

+ 741 - 0
ent/compapijob_update.go

@@ -0,0 +1,741 @@
+// Code generated by ent, DO NOT EDIT.
+
+package ent
+
+import (
+	"context"
+	"errors"
+	"fmt"
+	"time"
+	"wechat-api/ent/compapijob"
+	"wechat-api/ent/custom_types"
+	"wechat-api/ent/predicate"
+
+	"entgo.io/ent/dialect/sql"
+	"entgo.io/ent/dialect/sql/sqlgraph"
+	"entgo.io/ent/schema/field"
+)
+
+// CompapiJobUpdate is the builder for updating CompapiJob entities.
+type CompapiJobUpdate struct {
+	config
+	hooks    []Hook
+	mutation *CompapiJobMutation
+}
+
+// Where appends a list predicates to the CompapiJobUpdate builder.
+func (cju *CompapiJobUpdate) Where(ps ...predicate.CompapiJob) *CompapiJobUpdate {
+	cju.mutation.Where(ps...)
+	return cju
+}
+
+// SetUpdatedAt sets the "updated_at" field.
+func (cju *CompapiJobUpdate) SetUpdatedAt(t time.Time) *CompapiJobUpdate {
+	cju.mutation.SetUpdatedAt(t)
+	return cju
+}
+
+// SetDistAt sets the "dist_at" field.
+func (cju *CompapiJobUpdate) SetDistAt(t time.Time) *CompapiJobUpdate {
+	cju.mutation.SetDistAt(t)
+	return cju
+}
+
+// SetNillableDistAt sets the "dist_at" field if the given value is not nil.
+func (cju *CompapiJobUpdate) SetNillableDistAt(t *time.Time) *CompapiJobUpdate {
+	if t != nil {
+		cju.SetDistAt(*t)
+	}
+	return cju
+}
+
+// ClearDistAt clears the value of the "dist_at" field.
+func (cju *CompapiJobUpdate) ClearDistAt() *CompapiJobUpdate {
+	cju.mutation.ClearDistAt()
+	return cju
+}
+
+// SetDistStatus sets the "dist_status" field.
+func (cju *CompapiJobUpdate) SetDistStatus(i int8) *CompapiJobUpdate {
+	cju.mutation.ResetDistStatus()
+	cju.mutation.SetDistStatus(i)
+	return cju
+}
+
+// SetNillableDistStatus sets the "dist_status" field if the given value is not nil.
+func (cju *CompapiJobUpdate) SetNillableDistStatus(i *int8) *CompapiJobUpdate {
+	if i != nil {
+		cju.SetDistStatus(*i)
+	}
+	return cju
+}
+
+// AddDistStatus adds i to the "dist_status" field.
+func (cju *CompapiJobUpdate) AddDistStatus(i int8) *CompapiJobUpdate {
+	cju.mutation.AddDistStatus(i)
+	return cju
+}
+
+// ClearDistStatus clears the value of the "dist_status" field.
+func (cju *CompapiJobUpdate) ClearDistStatus() *CompapiJobUpdate {
+	cju.mutation.ClearDistStatus()
+	return cju
+}
+
+// SetCallbackStatus sets the "callback_status" field.
+func (cju *CompapiJobUpdate) SetCallbackStatus(i int8) *CompapiJobUpdate {
+	cju.mutation.ResetCallbackStatus()
+	cju.mutation.SetCallbackStatus(i)
+	return cju
+}
+
+// SetNillableCallbackStatus sets the "callback_status" field if the given value is not nil.
+func (cju *CompapiJobUpdate) SetNillableCallbackStatus(i *int8) *CompapiJobUpdate {
+	if i != nil {
+		cju.SetCallbackStatus(*i)
+	}
+	return cju
+}
+
+// AddCallbackStatus adds i to the "callback_status" field.
+func (cju *CompapiJobUpdate) AddCallbackStatus(i int8) *CompapiJobUpdate {
+	cju.mutation.AddCallbackStatus(i)
+	return cju
+}
+
+// ClearCallbackStatus clears the value of the "callback_status" field.
+func (cju *CompapiJobUpdate) ClearCallbackStatus() *CompapiJobUpdate {
+	cju.mutation.ClearCallbackStatus()
+	return cju
+}
+
+// SetCallbackURL sets the "callback_url" field.
+func (cju *CompapiJobUpdate) SetCallbackURL(s string) *CompapiJobUpdate {
+	cju.mutation.SetCallbackURL(s)
+	return cju
+}
+
+// SetNillableCallbackURL sets the "callback_url" field if the given value is not nil.
+func (cju *CompapiJobUpdate) SetNillableCallbackURL(s *string) *CompapiJobUpdate {
+	if s != nil {
+		cju.SetCallbackURL(*s)
+	}
+	return cju
+}
+
+// SetRequestJSON sets the "request_json" field.
+func (cju *CompapiJobUpdate) SetRequestJSON(ctd custom_types.OriginalData) *CompapiJobUpdate {
+	cju.mutation.SetRequestJSON(ctd)
+	return cju
+}
+
+// SetNillableRequestJSON sets the "request_json" field if the given value is not nil.
+func (cju *CompapiJobUpdate) SetNillableRequestJSON(ctd *custom_types.OriginalData) *CompapiJobUpdate {
+	if ctd != nil {
+		cju.SetRequestJSON(*ctd)
+	}
+	return cju
+}
+
+// SetAuthToken sets the "auth_token" field.
+func (cju *CompapiJobUpdate) SetAuthToken(s string) *CompapiJobUpdate {
+	cju.mutation.SetAuthToken(s)
+	return cju
+}
+
+// SetNillableAuthToken sets the "auth_token" field if the given value is not nil.
+func (cju *CompapiJobUpdate) SetNillableAuthToken(s *string) *CompapiJobUpdate {
+	if s != nil {
+		cju.SetAuthToken(*s)
+	}
+	return cju
+}
+
+// SetEventType sets the "event_type" field.
+func (cju *CompapiJobUpdate) SetEventType(s string) *CompapiJobUpdate {
+	cju.mutation.SetEventType(s)
+	return cju
+}
+
+// SetNillableEventType sets the "event_type" field if the given value is not nil.
+func (cju *CompapiJobUpdate) SetNillableEventType(s *string) *CompapiJobUpdate {
+	if s != nil {
+		cju.SetEventType(*s)
+	}
+	return cju
+}
+
+// SetWorkidIdx sets the "workid_idx" field.
+func (cju *CompapiJobUpdate) SetWorkidIdx(i int8) *CompapiJobUpdate {
+	cju.mutation.ResetWorkidIdx()
+	cju.mutation.SetWorkidIdx(i)
+	return cju
+}
+
+// SetNillableWorkidIdx sets the "workid_idx" field if the given value is not nil.
+func (cju *CompapiJobUpdate) SetNillableWorkidIdx(i *int8) *CompapiJobUpdate {
+	if i != nil {
+		cju.SetWorkidIdx(*i)
+	}
+	return cju
+}
+
+// AddWorkidIdx adds i to the "workid_idx" field.
+func (cju *CompapiJobUpdate) AddWorkidIdx(i int8) *CompapiJobUpdate {
+	cju.mutation.AddWorkidIdx(i)
+	return cju
+}
+
+// ClearWorkidIdx clears the value of the "workid_idx" field.
+func (cju *CompapiJobUpdate) ClearWorkidIdx() *CompapiJobUpdate {
+	cju.mutation.ClearWorkidIdx()
+	return cju
+}
+
+// SetChatID sets the "chat_id" field.
+func (cju *CompapiJobUpdate) SetChatID(s string) *CompapiJobUpdate {
+	cju.mutation.SetChatID(s)
+	return cju
+}
+
+// SetNillableChatID sets the "chat_id" field if the given value is not nil.
+func (cju *CompapiJobUpdate) SetNillableChatID(s *string) *CompapiJobUpdate {
+	if s != nil {
+		cju.SetChatID(*s)
+	}
+	return cju
+}
+
+// ClearChatID clears the value of the "chat_id" field.
+func (cju *CompapiJobUpdate) ClearChatID() *CompapiJobUpdate {
+	cju.mutation.ClearChatID()
+	return cju
+}
+
+// SetRetryCount sets the "retry_count" field.
+func (cju *CompapiJobUpdate) SetRetryCount(i int8) *CompapiJobUpdate {
+	cju.mutation.ResetRetryCount()
+	cju.mutation.SetRetryCount(i)
+	return cju
+}
+
+// SetNillableRetryCount sets the "retry_count" field if the given value is not nil.
+func (cju *CompapiJobUpdate) SetNillableRetryCount(i *int8) *CompapiJobUpdate {
+	if i != nil {
+		cju.SetRetryCount(*i)
+	}
+	return cju
+}
+
+// AddRetryCount adds i to the "retry_count" field.
+func (cju *CompapiJobUpdate) AddRetryCount(i int8) *CompapiJobUpdate {
+	cju.mutation.AddRetryCount(i)
+	return cju
+}
+
+// ClearRetryCount clears the value of the "retry_count" field.
+func (cju *CompapiJobUpdate) ClearRetryCount() *CompapiJobUpdate {
+	cju.mutation.ClearRetryCount()
+	return cju
+}
+
+// Mutation returns the CompapiJobMutation object of the builder.
+func (cju *CompapiJobUpdate) Mutation() *CompapiJobMutation {
+	return cju.mutation
+}
+
+// Save executes the query and returns the number of nodes affected by the update operation.
+func (cju *CompapiJobUpdate) Save(ctx context.Context) (int, error) {
+	cju.defaults()
+	return withHooks(ctx, cju.sqlSave, cju.mutation, cju.hooks)
+}
+
+// SaveX is like Save, but panics if an error occurs.
+func (cju *CompapiJobUpdate) SaveX(ctx context.Context) int {
+	affected, err := cju.Save(ctx)
+	if err != nil {
+		panic(err)
+	}
+	return affected
+}
+
+// Exec executes the query.
+func (cju *CompapiJobUpdate) Exec(ctx context.Context) error {
+	_, err := cju.Save(ctx)
+	return err
+}
+
+// ExecX is like Exec, but panics if an error occurs.
+func (cju *CompapiJobUpdate) ExecX(ctx context.Context) {
+	if err := cju.Exec(ctx); err != nil {
+		panic(err)
+	}
+}
+
+// defaults sets the default values of the builder before save.
+func (cju *CompapiJobUpdate) defaults() {
+	if _, ok := cju.mutation.UpdatedAt(); !ok {
+		v := compapijob.UpdateDefaultUpdatedAt()
+		cju.mutation.SetUpdatedAt(v)
+	}
+}
+
+func (cju *CompapiJobUpdate) sqlSave(ctx context.Context) (n int, err error) {
+	_spec := sqlgraph.NewUpdateSpec(compapijob.Table, compapijob.Columns, sqlgraph.NewFieldSpec(compapijob.FieldID, field.TypeUint64))
+	if ps := cju.mutation.predicates; len(ps) > 0 {
+		_spec.Predicate = func(selector *sql.Selector) {
+			for i := range ps {
+				ps[i](selector)
+			}
+		}
+	}
+	if value, ok := cju.mutation.UpdatedAt(); ok {
+		_spec.SetField(compapijob.FieldUpdatedAt, field.TypeTime, value)
+	}
+	if value, ok := cju.mutation.DistAt(); ok {
+		_spec.SetField(compapijob.FieldDistAt, field.TypeTime, value)
+	}
+	if cju.mutation.DistAtCleared() {
+		_spec.ClearField(compapijob.FieldDistAt, field.TypeTime)
+	}
+	if value, ok := cju.mutation.DistStatus(); ok {
+		_spec.SetField(compapijob.FieldDistStatus, field.TypeInt8, value)
+	}
+	if value, ok := cju.mutation.AddedDistStatus(); ok {
+		_spec.AddField(compapijob.FieldDistStatus, field.TypeInt8, value)
+	}
+	if cju.mutation.DistStatusCleared() {
+		_spec.ClearField(compapijob.FieldDistStatus, field.TypeInt8)
+	}
+	if value, ok := cju.mutation.CallbackStatus(); ok {
+		_spec.SetField(compapijob.FieldCallbackStatus, field.TypeInt8, value)
+	}
+	if value, ok := cju.mutation.AddedCallbackStatus(); ok {
+		_spec.AddField(compapijob.FieldCallbackStatus, field.TypeInt8, value)
+	}
+	if cju.mutation.CallbackStatusCleared() {
+		_spec.ClearField(compapijob.FieldCallbackStatus, field.TypeInt8)
+	}
+	if value, ok := cju.mutation.CallbackURL(); ok {
+		_spec.SetField(compapijob.FieldCallbackURL, field.TypeString, value)
+	}
+	if value, ok := cju.mutation.RequestJSON(); ok {
+		_spec.SetField(compapijob.FieldRequestJSON, field.TypeJSON, value)
+	}
+	if value, ok := cju.mutation.AuthToken(); ok {
+		_spec.SetField(compapijob.FieldAuthToken, field.TypeString, value)
+	}
+	if value, ok := cju.mutation.EventType(); ok {
+		_spec.SetField(compapijob.FieldEventType, field.TypeString, value)
+	}
+	if value, ok := cju.mutation.WorkidIdx(); ok {
+		_spec.SetField(compapijob.FieldWorkidIdx, field.TypeInt8, value)
+	}
+	if value, ok := cju.mutation.AddedWorkidIdx(); ok {
+		_spec.AddField(compapijob.FieldWorkidIdx, field.TypeInt8, value)
+	}
+	if cju.mutation.WorkidIdxCleared() {
+		_spec.ClearField(compapijob.FieldWorkidIdx, field.TypeInt8)
+	}
+	if value, ok := cju.mutation.ChatID(); ok {
+		_spec.SetField(compapijob.FieldChatID, field.TypeString, value)
+	}
+	if cju.mutation.ChatIDCleared() {
+		_spec.ClearField(compapijob.FieldChatID, field.TypeString)
+	}
+	if value, ok := cju.mutation.RetryCount(); ok {
+		_spec.SetField(compapijob.FieldRetryCount, field.TypeInt8, value)
+	}
+	if value, ok := cju.mutation.AddedRetryCount(); ok {
+		_spec.AddField(compapijob.FieldRetryCount, field.TypeInt8, value)
+	}
+	if cju.mutation.RetryCountCleared() {
+		_spec.ClearField(compapijob.FieldRetryCount, field.TypeInt8)
+	}
+	if n, err = sqlgraph.UpdateNodes(ctx, cju.driver, _spec); err != nil {
+		if _, ok := err.(*sqlgraph.NotFoundError); ok {
+			err = &NotFoundError{compapijob.Label}
+		} else if sqlgraph.IsConstraintError(err) {
+			err = &ConstraintError{msg: err.Error(), wrap: err}
+		}
+		return 0, err
+	}
+	cju.mutation.done = true
+	return n, nil
+}
+
+// CompapiJobUpdateOne is the builder for updating a single CompapiJob entity.
+type CompapiJobUpdateOne struct {
+	config
+	fields   []string
+	hooks    []Hook
+	mutation *CompapiJobMutation
+}
+
+// SetUpdatedAt sets the "updated_at" field.
+func (cjuo *CompapiJobUpdateOne) SetUpdatedAt(t time.Time) *CompapiJobUpdateOne {
+	cjuo.mutation.SetUpdatedAt(t)
+	return cjuo
+}
+
+// SetDistAt sets the "dist_at" field.
+func (cjuo *CompapiJobUpdateOne) SetDistAt(t time.Time) *CompapiJobUpdateOne {
+	cjuo.mutation.SetDistAt(t)
+	return cjuo
+}
+
+// SetNillableDistAt sets the "dist_at" field if the given value is not nil.
+func (cjuo *CompapiJobUpdateOne) SetNillableDistAt(t *time.Time) *CompapiJobUpdateOne {
+	if t != nil {
+		cjuo.SetDistAt(*t)
+	}
+	return cjuo
+}
+
+// ClearDistAt clears the value of the "dist_at" field.
+func (cjuo *CompapiJobUpdateOne) ClearDistAt() *CompapiJobUpdateOne {
+	cjuo.mutation.ClearDistAt()
+	return cjuo
+}
+
+// SetDistStatus sets the "dist_status" field.
+func (cjuo *CompapiJobUpdateOne) SetDistStatus(i int8) *CompapiJobUpdateOne {
+	cjuo.mutation.ResetDistStatus()
+	cjuo.mutation.SetDistStatus(i)
+	return cjuo
+}
+
+// SetNillableDistStatus sets the "dist_status" field if the given value is not nil.
+func (cjuo *CompapiJobUpdateOne) SetNillableDistStatus(i *int8) *CompapiJobUpdateOne {
+	if i != nil {
+		cjuo.SetDistStatus(*i)
+	}
+	return cjuo
+}
+
+// AddDistStatus adds i to the "dist_status" field.
+func (cjuo *CompapiJobUpdateOne) AddDistStatus(i int8) *CompapiJobUpdateOne {
+	cjuo.mutation.AddDistStatus(i)
+	return cjuo
+}
+
+// ClearDistStatus clears the value of the "dist_status" field.
+func (cjuo *CompapiJobUpdateOne) ClearDistStatus() *CompapiJobUpdateOne {
+	cjuo.mutation.ClearDistStatus()
+	return cjuo
+}
+
+// SetCallbackStatus sets the "callback_status" field.
+func (cjuo *CompapiJobUpdateOne) SetCallbackStatus(i int8) *CompapiJobUpdateOne {
+	cjuo.mutation.ResetCallbackStatus()
+	cjuo.mutation.SetCallbackStatus(i)
+	return cjuo
+}
+
+// SetNillableCallbackStatus sets the "callback_status" field if the given value is not nil.
+func (cjuo *CompapiJobUpdateOne) SetNillableCallbackStatus(i *int8) *CompapiJobUpdateOne {
+	if i != nil {
+		cjuo.SetCallbackStatus(*i)
+	}
+	return cjuo
+}
+
+// AddCallbackStatus adds i to the "callback_status" field.
+func (cjuo *CompapiJobUpdateOne) AddCallbackStatus(i int8) *CompapiJobUpdateOne {
+	cjuo.mutation.AddCallbackStatus(i)
+	return cjuo
+}
+
+// ClearCallbackStatus clears the value of the "callback_status" field.
+func (cjuo *CompapiJobUpdateOne) ClearCallbackStatus() *CompapiJobUpdateOne {
+	cjuo.mutation.ClearCallbackStatus()
+	return cjuo
+}
+
+// SetCallbackURL sets the "callback_url" field.
+func (cjuo *CompapiJobUpdateOne) SetCallbackURL(s string) *CompapiJobUpdateOne {
+	cjuo.mutation.SetCallbackURL(s)
+	return cjuo
+}
+
+// SetNillableCallbackURL sets the "callback_url" field if the given value is not nil.
+func (cjuo *CompapiJobUpdateOne) SetNillableCallbackURL(s *string) *CompapiJobUpdateOne {
+	if s != nil {
+		cjuo.SetCallbackURL(*s)
+	}
+	return cjuo
+}
+
+// SetRequestJSON sets the "request_json" field.
+func (cjuo *CompapiJobUpdateOne) SetRequestJSON(ctd custom_types.OriginalData) *CompapiJobUpdateOne {
+	cjuo.mutation.SetRequestJSON(ctd)
+	return cjuo
+}
+
+// SetNillableRequestJSON sets the "request_json" field if the given value is not nil.
+func (cjuo *CompapiJobUpdateOne) SetNillableRequestJSON(ctd *custom_types.OriginalData) *CompapiJobUpdateOne {
+	if ctd != nil {
+		cjuo.SetRequestJSON(*ctd)
+	}
+	return cjuo
+}
+
+// SetAuthToken sets the "auth_token" field.
+func (cjuo *CompapiJobUpdateOne) SetAuthToken(s string) *CompapiJobUpdateOne {
+	cjuo.mutation.SetAuthToken(s)
+	return cjuo
+}
+
+// SetNillableAuthToken sets the "auth_token" field if the given value is not nil.
+func (cjuo *CompapiJobUpdateOne) SetNillableAuthToken(s *string) *CompapiJobUpdateOne {
+	if s != nil {
+		cjuo.SetAuthToken(*s)
+	}
+	return cjuo
+}
+
+// SetEventType sets the "event_type" field.
+func (cjuo *CompapiJobUpdateOne) SetEventType(s string) *CompapiJobUpdateOne {
+	cjuo.mutation.SetEventType(s)
+	return cjuo
+}
+
+// SetNillableEventType sets the "event_type" field if the given value is not nil.
+func (cjuo *CompapiJobUpdateOne) SetNillableEventType(s *string) *CompapiJobUpdateOne {
+	if s != nil {
+		cjuo.SetEventType(*s)
+	}
+	return cjuo
+}
+
+// SetWorkidIdx sets the "workid_idx" field.
+func (cjuo *CompapiJobUpdateOne) SetWorkidIdx(i int8) *CompapiJobUpdateOne {
+	cjuo.mutation.ResetWorkidIdx()
+	cjuo.mutation.SetWorkidIdx(i)
+	return cjuo
+}
+
+// SetNillableWorkidIdx sets the "workid_idx" field if the given value is not nil.
+func (cjuo *CompapiJobUpdateOne) SetNillableWorkidIdx(i *int8) *CompapiJobUpdateOne {
+	if i != nil {
+		cjuo.SetWorkidIdx(*i)
+	}
+	return cjuo
+}
+
+// AddWorkidIdx adds i to the "workid_idx" field.
+func (cjuo *CompapiJobUpdateOne) AddWorkidIdx(i int8) *CompapiJobUpdateOne {
+	cjuo.mutation.AddWorkidIdx(i)
+	return cjuo
+}
+
+// ClearWorkidIdx clears the value of the "workid_idx" field.
+func (cjuo *CompapiJobUpdateOne) ClearWorkidIdx() *CompapiJobUpdateOne {
+	cjuo.mutation.ClearWorkidIdx()
+	return cjuo
+}
+
+// SetChatID sets the "chat_id" field.
+func (cjuo *CompapiJobUpdateOne) SetChatID(s string) *CompapiJobUpdateOne {
+	cjuo.mutation.SetChatID(s)
+	return cjuo
+}
+
+// SetNillableChatID sets the "chat_id" field if the given value is not nil.
+func (cjuo *CompapiJobUpdateOne) SetNillableChatID(s *string) *CompapiJobUpdateOne {
+	if s != nil {
+		cjuo.SetChatID(*s)
+	}
+	return cjuo
+}
+
+// ClearChatID clears the value of the "chat_id" field.
+func (cjuo *CompapiJobUpdateOne) ClearChatID() *CompapiJobUpdateOne {
+	cjuo.mutation.ClearChatID()
+	return cjuo
+}
+
+// SetRetryCount sets the "retry_count" field.
+func (cjuo *CompapiJobUpdateOne) SetRetryCount(i int8) *CompapiJobUpdateOne {
+	cjuo.mutation.ResetRetryCount()
+	cjuo.mutation.SetRetryCount(i)
+	return cjuo
+}
+
+// SetNillableRetryCount sets the "retry_count" field if the given value is not nil.
+func (cjuo *CompapiJobUpdateOne) SetNillableRetryCount(i *int8) *CompapiJobUpdateOne {
+	if i != nil {
+		cjuo.SetRetryCount(*i)
+	}
+	return cjuo
+}
+
+// AddRetryCount adds i to the "retry_count" field.
+func (cjuo *CompapiJobUpdateOne) AddRetryCount(i int8) *CompapiJobUpdateOne {
+	cjuo.mutation.AddRetryCount(i)
+	return cjuo
+}
+
+// ClearRetryCount clears the value of the "retry_count" field.
+func (cjuo *CompapiJobUpdateOne) ClearRetryCount() *CompapiJobUpdateOne {
+	cjuo.mutation.ClearRetryCount()
+	return cjuo
+}
+
+// Mutation returns the CompapiJobMutation object of the builder.
+func (cjuo *CompapiJobUpdateOne) Mutation() *CompapiJobMutation {
+	return cjuo.mutation
+}
+
+// Where appends a list predicates to the CompapiJobUpdate builder.
+func (cjuo *CompapiJobUpdateOne) Where(ps ...predicate.CompapiJob) *CompapiJobUpdateOne {
+	cjuo.mutation.Where(ps...)
+	return cjuo
+}
+
+// Select allows selecting one or more fields (columns) of the returned entity.
+// The default is selecting all fields defined in the entity schema.
+func (cjuo *CompapiJobUpdateOne) Select(field string, fields ...string) *CompapiJobUpdateOne {
+	cjuo.fields = append([]string{field}, fields...)
+	return cjuo
+}
+
+// Save executes the query and returns the updated CompapiJob entity.
+func (cjuo *CompapiJobUpdateOne) Save(ctx context.Context) (*CompapiJob, error) {
+	cjuo.defaults()
+	return withHooks(ctx, cjuo.sqlSave, cjuo.mutation, cjuo.hooks)
+}
+
+// SaveX is like Save, but panics if an error occurs.
+func (cjuo *CompapiJobUpdateOne) SaveX(ctx context.Context) *CompapiJob {
+	node, err := cjuo.Save(ctx)
+	if err != nil {
+		panic(err)
+	}
+	return node
+}
+
+// Exec executes the query on the entity.
+func (cjuo *CompapiJobUpdateOne) Exec(ctx context.Context) error {
+	_, err := cjuo.Save(ctx)
+	return err
+}
+
+// ExecX is like Exec, but panics if an error occurs.
+func (cjuo *CompapiJobUpdateOne) ExecX(ctx context.Context) {
+	if err := cjuo.Exec(ctx); err != nil {
+		panic(err)
+	}
+}
+
+// defaults sets the default values of the builder before save.
+func (cjuo *CompapiJobUpdateOne) defaults() {
+	if _, ok := cjuo.mutation.UpdatedAt(); !ok {
+		v := compapijob.UpdateDefaultUpdatedAt()
+		cjuo.mutation.SetUpdatedAt(v)
+	}
+}
+
+func (cjuo *CompapiJobUpdateOne) sqlSave(ctx context.Context) (_node *CompapiJob, err error) {
+	_spec := sqlgraph.NewUpdateSpec(compapijob.Table, compapijob.Columns, sqlgraph.NewFieldSpec(compapijob.FieldID, field.TypeUint64))
+	id, ok := cjuo.mutation.ID()
+	if !ok {
+		return nil, &ValidationError{Name: "id", err: errors.New(`ent: missing "CompapiJob.id" for update`)}
+	}
+	_spec.Node.ID.Value = id
+	if fields := cjuo.fields; len(fields) > 0 {
+		_spec.Node.Columns = make([]string, 0, len(fields))
+		_spec.Node.Columns = append(_spec.Node.Columns, compapijob.FieldID)
+		for _, f := range fields {
+			if !compapijob.ValidColumn(f) {
+				return nil, &ValidationError{Name: f, err: fmt.Errorf("ent: invalid field %q for query", f)}
+			}
+			if f != compapijob.FieldID {
+				_spec.Node.Columns = append(_spec.Node.Columns, f)
+			}
+		}
+	}
+	if ps := cjuo.mutation.predicates; len(ps) > 0 {
+		_spec.Predicate = func(selector *sql.Selector) {
+			for i := range ps {
+				ps[i](selector)
+			}
+		}
+	}
+	if value, ok := cjuo.mutation.UpdatedAt(); ok {
+		_spec.SetField(compapijob.FieldUpdatedAt, field.TypeTime, value)
+	}
+	if value, ok := cjuo.mutation.DistAt(); ok {
+		_spec.SetField(compapijob.FieldDistAt, field.TypeTime, value)
+	}
+	if cjuo.mutation.DistAtCleared() {
+		_spec.ClearField(compapijob.FieldDistAt, field.TypeTime)
+	}
+	if value, ok := cjuo.mutation.DistStatus(); ok {
+		_spec.SetField(compapijob.FieldDistStatus, field.TypeInt8, value)
+	}
+	if value, ok := cjuo.mutation.AddedDistStatus(); ok {
+		_spec.AddField(compapijob.FieldDistStatus, field.TypeInt8, value)
+	}
+	if cjuo.mutation.DistStatusCleared() {
+		_spec.ClearField(compapijob.FieldDistStatus, field.TypeInt8)
+	}
+	if value, ok := cjuo.mutation.CallbackStatus(); ok {
+		_spec.SetField(compapijob.FieldCallbackStatus, field.TypeInt8, value)
+	}
+	if value, ok := cjuo.mutation.AddedCallbackStatus(); ok {
+		_spec.AddField(compapijob.FieldCallbackStatus, field.TypeInt8, value)
+	}
+	if cjuo.mutation.CallbackStatusCleared() {
+		_spec.ClearField(compapijob.FieldCallbackStatus, field.TypeInt8)
+	}
+	if value, ok := cjuo.mutation.CallbackURL(); ok {
+		_spec.SetField(compapijob.FieldCallbackURL, field.TypeString, value)
+	}
+	if value, ok := cjuo.mutation.RequestJSON(); ok {
+		_spec.SetField(compapijob.FieldRequestJSON, field.TypeJSON, value)
+	}
+	if value, ok := cjuo.mutation.AuthToken(); ok {
+		_spec.SetField(compapijob.FieldAuthToken, field.TypeString, value)
+	}
+	if value, ok := cjuo.mutation.EventType(); ok {
+		_spec.SetField(compapijob.FieldEventType, field.TypeString, value)
+	}
+	if value, ok := cjuo.mutation.WorkidIdx(); ok {
+		_spec.SetField(compapijob.FieldWorkidIdx, field.TypeInt8, value)
+	}
+	if value, ok := cjuo.mutation.AddedWorkidIdx(); ok {
+		_spec.AddField(compapijob.FieldWorkidIdx, field.TypeInt8, value)
+	}
+	if cjuo.mutation.WorkidIdxCleared() {
+		_spec.ClearField(compapijob.FieldWorkidIdx, field.TypeInt8)
+	}
+	if value, ok := cjuo.mutation.ChatID(); ok {
+		_spec.SetField(compapijob.FieldChatID, field.TypeString, value)
+	}
+	if cjuo.mutation.ChatIDCleared() {
+		_spec.ClearField(compapijob.FieldChatID, field.TypeString)
+	}
+	if value, ok := cjuo.mutation.RetryCount(); ok {
+		_spec.SetField(compapijob.FieldRetryCount, field.TypeInt8, value)
+	}
+	if value, ok := cjuo.mutation.AddedRetryCount(); ok {
+		_spec.AddField(compapijob.FieldRetryCount, field.TypeInt8, value)
+	}
+	if cjuo.mutation.RetryCountCleared() {
+		_spec.ClearField(compapijob.FieldRetryCount, field.TypeInt8)
+	}
+	_node = &CompapiJob{config: cjuo.config}
+	_spec.Assign = _node.assignValues
+	_spec.ScanValues = _node.scanValues
+	if err = sqlgraph.UpdateNode(ctx, cjuo.driver, _spec); err != nil {
+		if _, ok := err.(*sqlgraph.NotFoundError); ok {
+			err = &NotFoundError{compapijob.Label}
+		} else if sqlgraph.IsConstraintError(err) {
+			err = &ConstraintError{msg: err.Error(), wrap: err}
+		}
+		return nil, err
+	}
+	cjuo.mutation.done = true
+	return _node, nil
+}

+ 2 - 0
ent/ent.go

@@ -17,6 +17,7 @@ import (
 	"wechat-api/ent/category"
 	"wechat-api/ent/chatrecords"
 	"wechat-api/ent/chatsession"
+	"wechat-api/ent/compapijob"
 	"wechat-api/ent/contact"
 	"wechat-api/ent/creditbalance"
 	"wechat-api/ent/creditusage"
@@ -122,6 +123,7 @@ func checkColumn(table, column string) error {
 			category.Table:            category.ValidColumn,
 			chatrecords.Table:         chatrecords.ValidColumn,
 			chatsession.Table:         chatsession.ValidColumn,
+			compapijob.Table:          compapijob.ValidColumn,
 			contact.Table:             contact.ValidColumn,
 			creditbalance.Table:       creditbalance.ValidColumn,
 			creditusage.Table:         creditusage.ValidColumn,

+ 12 - 0
ent/hook/hook.go

@@ -116,6 +116,18 @@ func (f ChatSessionFunc) Mutate(ctx context.Context, m ent.Mutation) (ent.Value,
 	return nil, fmt.Errorf("unexpected mutation type %T. expect *ent.ChatSessionMutation", m)
 }
 
+// The CompapiJobFunc type is an adapter to allow the use of ordinary
+// function as CompapiJob mutator.
+type CompapiJobFunc func(context.Context, *ent.CompapiJobMutation) (ent.Value, error)
+
+// Mutate calls f(ctx, m).
+func (f CompapiJobFunc) Mutate(ctx context.Context, m ent.Mutation) (ent.Value, error) {
+	if mv, ok := m.(*ent.CompapiJobMutation); ok {
+		return f(ctx, mv)
+	}
+	return nil, fmt.Errorf("unexpected mutation type %T. expect *ent.CompapiJobMutation", m)
+}
+
 // The ContactFunc type is an adapter to allow the use of ordinary
 // function as Contact mutator.
 type ContactFunc func(context.Context, *ent.ContactMutation) (ent.Value, error)

+ 30 - 0
ent/intercept/intercept.go

@@ -15,6 +15,7 @@ import (
 	"wechat-api/ent/category"
 	"wechat-api/ent/chatrecords"
 	"wechat-api/ent/chatsession"
+	"wechat-api/ent/compapijob"
 	"wechat-api/ent/contact"
 	"wechat-api/ent/creditbalance"
 	"wechat-api/ent/creditusage"
@@ -351,6 +352,33 @@ func (f TraverseChatSession) Traverse(ctx context.Context, q ent.Query) error {
 	return fmt.Errorf("unexpected query type %T. expect *ent.ChatSessionQuery", q)
 }
 
+// The CompapiJobFunc type is an adapter to allow the use of ordinary function as a Querier.
+type CompapiJobFunc func(context.Context, *ent.CompapiJobQuery) (ent.Value, error)
+
+// Query calls f(ctx, q).
+func (f CompapiJobFunc) Query(ctx context.Context, q ent.Query) (ent.Value, error) {
+	if q, ok := q.(*ent.CompapiJobQuery); ok {
+		return f(ctx, q)
+	}
+	return nil, fmt.Errorf("unexpected query type %T. expect *ent.CompapiJobQuery", q)
+}
+
+// The TraverseCompapiJob type is an adapter to allow the use of ordinary function as Traverser.
+type TraverseCompapiJob func(context.Context, *ent.CompapiJobQuery) error
+
+// Intercept is a dummy implementation of Intercept that returns the next Querier in the pipeline.
+func (f TraverseCompapiJob) Intercept(next ent.Querier) ent.Querier {
+	return next
+}
+
+// Traverse calls f(ctx, q).
+func (f TraverseCompapiJob) Traverse(ctx context.Context, q ent.Query) error {
+	if q, ok := q.(*ent.CompapiJobQuery); ok {
+		return f(ctx, q)
+	}
+	return fmt.Errorf("unexpected query type %T. expect *ent.CompapiJobQuery", q)
+}
+
 // The ContactFunc type is an adapter to allow the use of ordinary function as a Querier.
 type ContactFunc func(context.Context, *ent.ContactQuery) (ent.Value, error)
 
@@ -1236,6 +1264,8 @@ func NewQuery(q ent.Query) (Query, error) {
 		return &query[*ent.ChatRecordsQuery, predicate.ChatRecords, chatrecords.OrderOption]{typ: ent.TypeChatRecords, tq: q}, nil
 	case *ent.ChatSessionQuery:
 		return &query[*ent.ChatSessionQuery, predicate.ChatSession, chatsession.OrderOption]{typ: ent.TypeChatSession, tq: q}, nil
+	case *ent.CompapiJobQuery:
+		return &query[*ent.CompapiJobQuery, predicate.CompapiJob, compapijob.OrderOption]{typ: ent.TypeCompapiJob, tq: q}, nil
 	case *ent.ContactQuery:
 		return &query[*ent.ContactQuery, predicate.Contact, contact.OrderOption]{typ: ent.TypeContact, tq: q}, nil
 	case *ent.CreditBalanceQuery:

+ 38 - 0
ent/migrate/schema.go

@@ -273,6 +273,40 @@ var (
 			},
 		},
 	}
+	// CompapiJobColumns holds the columns for the "compapi_job" table.
+	CompapiJobColumns = []*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: "dist_at", Type: field.TypeTime, Nullable: true, Comment: "Dist Time | 分发时间"},
+		{Name: "dist_status", Type: field.TypeInt8, Nullable: true, Comment: "dist status | 分发状态 0 未 1 已", Default: 0},
+		{Name: "callback_status", Type: field.TypeInt8, Nullable: true, Comment: "callback_status | 回调状态 10 准备回调 20 ", Default: 10},
+		{Name: "callback_url", Type: field.TypeString, Comment: "异步执行回调地址"},
+		{Name: "request_json", Type: field.TypeJSON, Comment: "请求参数结构JSON"},
+		{Name: "auth_token", Type: field.TypeString, Comment: "发起请求者的授权token", Default: ""},
+		{Name: "event_type", Type: field.TypeString, Comment: "发起请求者的类型", Default: ""},
+		{Name: "workid_idx", Type: field.TypeInt8, Nullable: true, Comment: "workId在字典中的索引", Default: 0},
+		{Name: "chat_id", Type: field.TypeString, Nullable: true, Comment: "会话ID", Default: ""},
+		{Name: "retry_count", Type: field.TypeInt8, Nullable: true, Comment: "retry count | 重试次数", Default: 0},
+	}
+	// CompapiJobTable holds the schema information for the "compapi_job" table.
+	CompapiJobTable = &schema.Table{
+		Name:       "compapi_job",
+		Columns:    CompapiJobColumns,
+		PrimaryKey: []*schema.Column{CompapiJobColumns[0]},
+		Indexes: []*schema.Index{
+			{
+				Name:    "compapijob_dist_status",
+				Unique:  false,
+				Columns: []*schema.Column{CompapiJobColumns[4]},
+			},
+			{
+				Name:    "compapijob_callback_status",
+				Unique:  false,
+				Columns: []*schema.Column{CompapiJobColumns[5]},
+			},
+		},
+	}
 	// ContactColumns holds the columns for the "contact" table.
 	ContactColumns = []*schema.Column{
 		{Name: "id", Type: field.TypeUint64, Increment: true},
@@ -1423,6 +1457,7 @@ var (
 		CategoryTable,
 		ChatRecordsTable,
 		ChatSessionTable,
+		CompapiJobTable,
 		ContactTable,
 		CreditBalanceTable,
 		CreditUsageTable,
@@ -1487,6 +1522,9 @@ func init() {
 	ChatSessionTable.Annotation = &entsql.Annotation{
 		Table: "chat_session",
 	}
+	CompapiJobTable.Annotation = &entsql.Annotation{
+		Table: "compapi_job",
+	}
 	ContactTable.Annotation = &entsql.Annotation{
 		Table: "contact",
 	}

+ 1184 - 0
ent/mutation.go

@@ -17,6 +17,7 @@ import (
 	"wechat-api/ent/category"
 	"wechat-api/ent/chatrecords"
 	"wechat-api/ent/chatsession"
+	"wechat-api/ent/compapijob"
 	"wechat-api/ent/contact"
 	"wechat-api/ent/creditbalance"
 	"wechat-api/ent/creditusage"
@@ -74,6 +75,7 @@ const (
 	TypeCategory            = "Category"
 	TypeChatRecords         = "ChatRecords"
 	TypeChatSession         = "ChatSession"
+	TypeCompapiJob          = "CompapiJob"
 	TypeContact             = "Contact"
 	TypeCreditBalance       = "CreditBalance"
 	TypeCreditUsage         = "CreditUsage"
@@ -10062,6 +10064,1188 @@ func (m *ChatSessionMutation) ResetEdge(name string) error {
 	return fmt.Errorf("unknown ChatSession edge %s", name)
 }
 
+// CompapiJobMutation represents an operation that mutates the CompapiJob nodes in the graph.
+type CompapiJobMutation struct {
+	config
+	op                 Op
+	typ                string
+	id                 *uint64
+	created_at         *time.Time
+	updated_at         *time.Time
+	dist_at            *time.Time
+	dist_status        *int8
+	adddist_status     *int8
+	callback_status    *int8
+	addcallback_status *int8
+	callback_url       *string
+	request_json       *custom_types.OriginalData
+	auth_token         *string
+	event_type         *string
+	workid_idx         *int8
+	addworkid_idx      *int8
+	chat_id            *string
+	retry_count        *int8
+	addretry_count     *int8
+	clearedFields      map[string]struct{}
+	done               bool
+	oldValue           func(context.Context) (*CompapiJob, error)
+	predicates         []predicate.CompapiJob
+}
+
+var _ ent.Mutation = (*CompapiJobMutation)(nil)
+
+// compapijobOption allows management of the mutation configuration using functional options.
+type compapijobOption func(*CompapiJobMutation)
+
+// newCompapiJobMutation creates new mutation for the CompapiJob entity.
+func newCompapiJobMutation(c config, op Op, opts ...compapijobOption) *CompapiJobMutation {
+	m := &CompapiJobMutation{
+		config:        c,
+		op:            op,
+		typ:           TypeCompapiJob,
+		clearedFields: make(map[string]struct{}),
+	}
+	for _, opt := range opts {
+		opt(m)
+	}
+	return m
+}
+
+// withCompapiJobID sets the ID field of the mutation.
+func withCompapiJobID(id uint64) compapijobOption {
+	return func(m *CompapiJobMutation) {
+		var (
+			err   error
+			once  sync.Once
+			value *CompapiJob
+		)
+		m.oldValue = func(ctx context.Context) (*CompapiJob, error) {
+			once.Do(func() {
+				if m.done {
+					err = errors.New("querying old values post mutation is not allowed")
+				} else {
+					value, err = m.Client().CompapiJob.Get(ctx, id)
+				}
+			})
+			return value, err
+		}
+		m.id = &id
+	}
+}
+
+// withCompapiJob sets the old CompapiJob of the mutation.
+func withCompapiJob(node *CompapiJob) compapijobOption {
+	return func(m *CompapiJobMutation) {
+		m.oldValue = func(context.Context) (*CompapiJob, 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 CompapiJobMutation) 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 CompapiJobMutation) 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 CompapiJob entities.
+func (m *CompapiJobMutation) 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 *CompapiJobMutation) 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 *CompapiJobMutation) 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().CompapiJob.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 *CompapiJobMutation) SetCreatedAt(t time.Time) {
+	m.created_at = &t
+}
+
+// CreatedAt returns the value of the "created_at" field in the mutation.
+func (m *CompapiJobMutation) 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 CompapiJob entity.
+// If the CompapiJob 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 *CompapiJobMutation) 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 *CompapiJobMutation) ResetCreatedAt() {
+	m.created_at = nil
+}
+
+// SetUpdatedAt sets the "updated_at" field.
+func (m *CompapiJobMutation) SetUpdatedAt(t time.Time) {
+	m.updated_at = &t
+}
+
+// UpdatedAt returns the value of the "updated_at" field in the mutation.
+func (m *CompapiJobMutation) 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 CompapiJob entity.
+// If the CompapiJob 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 *CompapiJobMutation) 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 *CompapiJobMutation) ResetUpdatedAt() {
+	m.updated_at = nil
+}
+
+// SetDistAt sets the "dist_at" field.
+func (m *CompapiJobMutation) SetDistAt(t time.Time) {
+	m.dist_at = &t
+}
+
+// DistAt returns the value of the "dist_at" field in the mutation.
+func (m *CompapiJobMutation) DistAt() (r time.Time, exists bool) {
+	v := m.dist_at
+	if v == nil {
+		return
+	}
+	return *v, true
+}
+
+// OldDistAt returns the old "dist_at" field's value of the CompapiJob entity.
+// If the CompapiJob 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 *CompapiJobMutation) OldDistAt(ctx context.Context) (v time.Time, err error) {
+	if !m.op.Is(OpUpdateOne) {
+		return v, errors.New("OldDistAt is only allowed on UpdateOne operations")
+	}
+	if m.id == nil || m.oldValue == nil {
+		return v, errors.New("OldDistAt requires an ID field in the mutation")
+	}
+	oldValue, err := m.oldValue(ctx)
+	if err != nil {
+		return v, fmt.Errorf("querying old value for OldDistAt: %w", err)
+	}
+	return oldValue.DistAt, nil
+}
+
+// ClearDistAt clears the value of the "dist_at" field.
+func (m *CompapiJobMutation) ClearDistAt() {
+	m.dist_at = nil
+	m.clearedFields[compapijob.FieldDistAt] = struct{}{}
+}
+
+// DistAtCleared returns if the "dist_at" field was cleared in this mutation.
+func (m *CompapiJobMutation) DistAtCleared() bool {
+	_, ok := m.clearedFields[compapijob.FieldDistAt]
+	return ok
+}
+
+// ResetDistAt resets all changes to the "dist_at" field.
+func (m *CompapiJobMutation) ResetDistAt() {
+	m.dist_at = nil
+	delete(m.clearedFields, compapijob.FieldDistAt)
+}
+
+// SetDistStatus sets the "dist_status" field.
+func (m *CompapiJobMutation) SetDistStatus(i int8) {
+	m.dist_status = &i
+	m.adddist_status = nil
+}
+
+// DistStatus returns the value of the "dist_status" field in the mutation.
+func (m *CompapiJobMutation) DistStatus() (r int8, exists bool) {
+	v := m.dist_status
+	if v == nil {
+		return
+	}
+	return *v, true
+}
+
+// OldDistStatus returns the old "dist_status" field's value of the CompapiJob entity.
+// If the CompapiJob 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 *CompapiJobMutation) OldDistStatus(ctx context.Context) (v int8, err error) {
+	if !m.op.Is(OpUpdateOne) {
+		return v, errors.New("OldDistStatus is only allowed on UpdateOne operations")
+	}
+	if m.id == nil || m.oldValue == nil {
+		return v, errors.New("OldDistStatus requires an ID field in the mutation")
+	}
+	oldValue, err := m.oldValue(ctx)
+	if err != nil {
+		return v, fmt.Errorf("querying old value for OldDistStatus: %w", err)
+	}
+	return oldValue.DistStatus, nil
+}
+
+// AddDistStatus adds i to the "dist_status" field.
+func (m *CompapiJobMutation) AddDistStatus(i int8) {
+	if m.adddist_status != nil {
+		*m.adddist_status += i
+	} else {
+		m.adddist_status = &i
+	}
+}
+
+// AddedDistStatus returns the value that was added to the "dist_status" field in this mutation.
+func (m *CompapiJobMutation) AddedDistStatus() (r int8, exists bool) {
+	v := m.adddist_status
+	if v == nil {
+		return
+	}
+	return *v, true
+}
+
+// ClearDistStatus clears the value of the "dist_status" field.
+func (m *CompapiJobMutation) ClearDistStatus() {
+	m.dist_status = nil
+	m.adddist_status = nil
+	m.clearedFields[compapijob.FieldDistStatus] = struct{}{}
+}
+
+// DistStatusCleared returns if the "dist_status" field was cleared in this mutation.
+func (m *CompapiJobMutation) DistStatusCleared() bool {
+	_, ok := m.clearedFields[compapijob.FieldDistStatus]
+	return ok
+}
+
+// ResetDistStatus resets all changes to the "dist_status" field.
+func (m *CompapiJobMutation) ResetDistStatus() {
+	m.dist_status = nil
+	m.adddist_status = nil
+	delete(m.clearedFields, compapijob.FieldDistStatus)
+}
+
+// SetCallbackStatus sets the "callback_status" field.
+func (m *CompapiJobMutation) SetCallbackStatus(i int8) {
+	m.callback_status = &i
+	m.addcallback_status = nil
+}
+
+// CallbackStatus returns the value of the "callback_status" field in the mutation.
+func (m *CompapiJobMutation) CallbackStatus() (r int8, exists bool) {
+	v := m.callback_status
+	if v == nil {
+		return
+	}
+	return *v, true
+}
+
+// OldCallbackStatus returns the old "callback_status" field's value of the CompapiJob entity.
+// If the CompapiJob 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 *CompapiJobMutation) OldCallbackStatus(ctx context.Context) (v int8, err error) {
+	if !m.op.Is(OpUpdateOne) {
+		return v, errors.New("OldCallbackStatus is only allowed on UpdateOne operations")
+	}
+	if m.id == nil || m.oldValue == nil {
+		return v, errors.New("OldCallbackStatus requires an ID field in the mutation")
+	}
+	oldValue, err := m.oldValue(ctx)
+	if err != nil {
+		return v, fmt.Errorf("querying old value for OldCallbackStatus: %w", err)
+	}
+	return oldValue.CallbackStatus, nil
+}
+
+// AddCallbackStatus adds i to the "callback_status" field.
+func (m *CompapiJobMutation) AddCallbackStatus(i int8) {
+	if m.addcallback_status != nil {
+		*m.addcallback_status += i
+	} else {
+		m.addcallback_status = &i
+	}
+}
+
+// AddedCallbackStatus returns the value that was added to the "callback_status" field in this mutation.
+func (m *CompapiJobMutation) AddedCallbackStatus() (r int8, exists bool) {
+	v := m.addcallback_status
+	if v == nil {
+		return
+	}
+	return *v, true
+}
+
+// ClearCallbackStatus clears the value of the "callback_status" field.
+func (m *CompapiJobMutation) ClearCallbackStatus() {
+	m.callback_status = nil
+	m.addcallback_status = nil
+	m.clearedFields[compapijob.FieldCallbackStatus] = struct{}{}
+}
+
+// CallbackStatusCleared returns if the "callback_status" field was cleared in this mutation.
+func (m *CompapiJobMutation) CallbackStatusCleared() bool {
+	_, ok := m.clearedFields[compapijob.FieldCallbackStatus]
+	return ok
+}
+
+// ResetCallbackStatus resets all changes to the "callback_status" field.
+func (m *CompapiJobMutation) ResetCallbackStatus() {
+	m.callback_status = nil
+	m.addcallback_status = nil
+	delete(m.clearedFields, compapijob.FieldCallbackStatus)
+}
+
+// SetCallbackURL sets the "callback_url" field.
+func (m *CompapiJobMutation) SetCallbackURL(s string) {
+	m.callback_url = &s
+}
+
+// CallbackURL returns the value of the "callback_url" field in the mutation.
+func (m *CompapiJobMutation) CallbackURL() (r string, exists bool) {
+	v := m.callback_url
+	if v == nil {
+		return
+	}
+	return *v, true
+}
+
+// OldCallbackURL returns the old "callback_url" field's value of the CompapiJob entity.
+// If the CompapiJob 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 *CompapiJobMutation) OldCallbackURL(ctx context.Context) (v string, err error) {
+	if !m.op.Is(OpUpdateOne) {
+		return v, errors.New("OldCallbackURL is only allowed on UpdateOne operations")
+	}
+	if m.id == nil || m.oldValue == nil {
+		return v, errors.New("OldCallbackURL requires an ID field in the mutation")
+	}
+	oldValue, err := m.oldValue(ctx)
+	if err != nil {
+		return v, fmt.Errorf("querying old value for OldCallbackURL: %w", err)
+	}
+	return oldValue.CallbackURL, nil
+}
+
+// ResetCallbackURL resets all changes to the "callback_url" field.
+func (m *CompapiJobMutation) ResetCallbackURL() {
+	m.callback_url = nil
+}
+
+// SetRequestJSON sets the "request_json" field.
+func (m *CompapiJobMutation) SetRequestJSON(ctd custom_types.OriginalData) {
+	m.request_json = &ctd
+}
+
+// RequestJSON returns the value of the "request_json" field in the mutation.
+func (m *CompapiJobMutation) RequestJSON() (r custom_types.OriginalData, exists bool) {
+	v := m.request_json
+	if v == nil {
+		return
+	}
+	return *v, true
+}
+
+// OldRequestJSON returns the old "request_json" field's value of the CompapiJob entity.
+// If the CompapiJob 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 *CompapiJobMutation) OldRequestJSON(ctx context.Context) (v custom_types.OriginalData, err error) {
+	if !m.op.Is(OpUpdateOne) {
+		return v, errors.New("OldRequestJSON is only allowed on UpdateOne operations")
+	}
+	if m.id == nil || m.oldValue == nil {
+		return v, errors.New("OldRequestJSON requires an ID field in the mutation")
+	}
+	oldValue, err := m.oldValue(ctx)
+	if err != nil {
+		return v, fmt.Errorf("querying old value for OldRequestJSON: %w", err)
+	}
+	return oldValue.RequestJSON, nil
+}
+
+// ResetRequestJSON resets all changes to the "request_json" field.
+func (m *CompapiJobMutation) ResetRequestJSON() {
+	m.request_json = nil
+}
+
+// SetAuthToken sets the "auth_token" field.
+func (m *CompapiJobMutation) SetAuthToken(s string) {
+	m.auth_token = &s
+}
+
+// AuthToken returns the value of the "auth_token" field in the mutation.
+func (m *CompapiJobMutation) AuthToken() (r string, exists bool) {
+	v := m.auth_token
+	if v == nil {
+		return
+	}
+	return *v, true
+}
+
+// OldAuthToken returns the old "auth_token" field's value of the CompapiJob entity.
+// If the CompapiJob 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 *CompapiJobMutation) OldAuthToken(ctx context.Context) (v string, err error) {
+	if !m.op.Is(OpUpdateOne) {
+		return v, errors.New("OldAuthToken is only allowed on UpdateOne operations")
+	}
+	if m.id == nil || m.oldValue == nil {
+		return v, errors.New("OldAuthToken requires an ID field in the mutation")
+	}
+	oldValue, err := m.oldValue(ctx)
+	if err != nil {
+		return v, fmt.Errorf("querying old value for OldAuthToken: %w", err)
+	}
+	return oldValue.AuthToken, nil
+}
+
+// ResetAuthToken resets all changes to the "auth_token" field.
+func (m *CompapiJobMutation) ResetAuthToken() {
+	m.auth_token = nil
+}
+
+// SetEventType sets the "event_type" field.
+func (m *CompapiJobMutation) SetEventType(s string) {
+	m.event_type = &s
+}
+
+// EventType returns the value of the "event_type" field in the mutation.
+func (m *CompapiJobMutation) EventType() (r string, exists bool) {
+	v := m.event_type
+	if v == nil {
+		return
+	}
+	return *v, true
+}
+
+// OldEventType returns the old "event_type" field's value of the CompapiJob entity.
+// If the CompapiJob 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 *CompapiJobMutation) OldEventType(ctx context.Context) (v string, err error) {
+	if !m.op.Is(OpUpdateOne) {
+		return v, errors.New("OldEventType is only allowed on UpdateOne operations")
+	}
+	if m.id == nil || m.oldValue == nil {
+		return v, errors.New("OldEventType requires an ID field in the mutation")
+	}
+	oldValue, err := m.oldValue(ctx)
+	if err != nil {
+		return v, fmt.Errorf("querying old value for OldEventType: %w", err)
+	}
+	return oldValue.EventType, nil
+}
+
+// ResetEventType resets all changes to the "event_type" field.
+func (m *CompapiJobMutation) ResetEventType() {
+	m.event_type = nil
+}
+
+// SetWorkidIdx sets the "workid_idx" field.
+func (m *CompapiJobMutation) SetWorkidIdx(i int8) {
+	m.workid_idx = &i
+	m.addworkid_idx = nil
+}
+
+// WorkidIdx returns the value of the "workid_idx" field in the mutation.
+func (m *CompapiJobMutation) WorkidIdx() (r int8, exists bool) {
+	v := m.workid_idx
+	if v == nil {
+		return
+	}
+	return *v, true
+}
+
+// OldWorkidIdx returns the old "workid_idx" field's value of the CompapiJob entity.
+// If the CompapiJob 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 *CompapiJobMutation) OldWorkidIdx(ctx context.Context) (v int8, err error) {
+	if !m.op.Is(OpUpdateOne) {
+		return v, errors.New("OldWorkidIdx is only allowed on UpdateOne operations")
+	}
+	if m.id == nil || m.oldValue == nil {
+		return v, errors.New("OldWorkidIdx requires an ID field in the mutation")
+	}
+	oldValue, err := m.oldValue(ctx)
+	if err != nil {
+		return v, fmt.Errorf("querying old value for OldWorkidIdx: %w", err)
+	}
+	return oldValue.WorkidIdx, nil
+}
+
+// AddWorkidIdx adds i to the "workid_idx" field.
+func (m *CompapiJobMutation) AddWorkidIdx(i int8) {
+	if m.addworkid_idx != nil {
+		*m.addworkid_idx += i
+	} else {
+		m.addworkid_idx = &i
+	}
+}
+
+// AddedWorkidIdx returns the value that was added to the "workid_idx" field in this mutation.
+func (m *CompapiJobMutation) AddedWorkidIdx() (r int8, exists bool) {
+	v := m.addworkid_idx
+	if v == nil {
+		return
+	}
+	return *v, true
+}
+
+// ClearWorkidIdx clears the value of the "workid_idx" field.
+func (m *CompapiJobMutation) ClearWorkidIdx() {
+	m.workid_idx = nil
+	m.addworkid_idx = nil
+	m.clearedFields[compapijob.FieldWorkidIdx] = struct{}{}
+}
+
+// WorkidIdxCleared returns if the "workid_idx" field was cleared in this mutation.
+func (m *CompapiJobMutation) WorkidIdxCleared() bool {
+	_, ok := m.clearedFields[compapijob.FieldWorkidIdx]
+	return ok
+}
+
+// ResetWorkidIdx resets all changes to the "workid_idx" field.
+func (m *CompapiJobMutation) ResetWorkidIdx() {
+	m.workid_idx = nil
+	m.addworkid_idx = nil
+	delete(m.clearedFields, compapijob.FieldWorkidIdx)
+}
+
+// SetChatID sets the "chat_id" field.
+func (m *CompapiJobMutation) SetChatID(s string) {
+	m.chat_id = &s
+}
+
+// ChatID returns the value of the "chat_id" field in the mutation.
+func (m *CompapiJobMutation) ChatID() (r string, exists bool) {
+	v := m.chat_id
+	if v == nil {
+		return
+	}
+	return *v, true
+}
+
+// OldChatID returns the old "chat_id" field's value of the CompapiJob entity.
+// If the CompapiJob 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 *CompapiJobMutation) OldChatID(ctx context.Context) (v string, err error) {
+	if !m.op.Is(OpUpdateOne) {
+		return v, errors.New("OldChatID is only allowed on UpdateOne operations")
+	}
+	if m.id == nil || m.oldValue == nil {
+		return v, errors.New("OldChatID requires an ID field in the mutation")
+	}
+	oldValue, err := m.oldValue(ctx)
+	if err != nil {
+		return v, fmt.Errorf("querying old value for OldChatID: %w", err)
+	}
+	return oldValue.ChatID, nil
+}
+
+// ClearChatID clears the value of the "chat_id" field.
+func (m *CompapiJobMutation) ClearChatID() {
+	m.chat_id = nil
+	m.clearedFields[compapijob.FieldChatID] = struct{}{}
+}
+
+// ChatIDCleared returns if the "chat_id" field was cleared in this mutation.
+func (m *CompapiJobMutation) ChatIDCleared() bool {
+	_, ok := m.clearedFields[compapijob.FieldChatID]
+	return ok
+}
+
+// ResetChatID resets all changes to the "chat_id" field.
+func (m *CompapiJobMutation) ResetChatID() {
+	m.chat_id = nil
+	delete(m.clearedFields, compapijob.FieldChatID)
+}
+
+// SetRetryCount sets the "retry_count" field.
+func (m *CompapiJobMutation) SetRetryCount(i int8) {
+	m.retry_count = &i
+	m.addretry_count = nil
+}
+
+// RetryCount returns the value of the "retry_count" field in the mutation.
+func (m *CompapiJobMutation) RetryCount() (r int8, exists bool) {
+	v := m.retry_count
+	if v == nil {
+		return
+	}
+	return *v, true
+}
+
+// OldRetryCount returns the old "retry_count" field's value of the CompapiJob entity.
+// If the CompapiJob 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 *CompapiJobMutation) OldRetryCount(ctx context.Context) (v int8, err error) {
+	if !m.op.Is(OpUpdateOne) {
+		return v, errors.New("OldRetryCount is only allowed on UpdateOne operations")
+	}
+	if m.id == nil || m.oldValue == nil {
+		return v, errors.New("OldRetryCount requires an ID field in the mutation")
+	}
+	oldValue, err := m.oldValue(ctx)
+	if err != nil {
+		return v, fmt.Errorf("querying old value for OldRetryCount: %w", err)
+	}
+	return oldValue.RetryCount, nil
+}
+
+// AddRetryCount adds i to the "retry_count" field.
+func (m *CompapiJobMutation) AddRetryCount(i int8) {
+	if m.addretry_count != nil {
+		*m.addretry_count += i
+	} else {
+		m.addretry_count = &i
+	}
+}
+
+// AddedRetryCount returns the value that was added to the "retry_count" field in this mutation.
+func (m *CompapiJobMutation) AddedRetryCount() (r int8, exists bool) {
+	v := m.addretry_count
+	if v == nil {
+		return
+	}
+	return *v, true
+}
+
+// ClearRetryCount clears the value of the "retry_count" field.
+func (m *CompapiJobMutation) ClearRetryCount() {
+	m.retry_count = nil
+	m.addretry_count = nil
+	m.clearedFields[compapijob.FieldRetryCount] = struct{}{}
+}
+
+// RetryCountCleared returns if the "retry_count" field was cleared in this mutation.
+func (m *CompapiJobMutation) RetryCountCleared() bool {
+	_, ok := m.clearedFields[compapijob.FieldRetryCount]
+	return ok
+}
+
+// ResetRetryCount resets all changes to the "retry_count" field.
+func (m *CompapiJobMutation) ResetRetryCount() {
+	m.retry_count = nil
+	m.addretry_count = nil
+	delete(m.clearedFields, compapijob.FieldRetryCount)
+}
+
+// Where appends a list predicates to the CompapiJobMutation builder.
+func (m *CompapiJobMutation) Where(ps ...predicate.CompapiJob) {
+	m.predicates = append(m.predicates, ps...)
+}
+
+// WhereP appends storage-level predicates to the CompapiJobMutation builder. Using this method,
+// users can use type-assertion to append predicates that do not depend on any generated package.
+func (m *CompapiJobMutation) WhereP(ps ...func(*sql.Selector)) {
+	p := make([]predicate.CompapiJob, len(ps))
+	for i := range ps {
+		p[i] = ps[i]
+	}
+	m.Where(p...)
+}
+
+// Op returns the operation name.
+func (m *CompapiJobMutation) Op() Op {
+	return m.op
+}
+
+// SetOp allows setting the mutation operation.
+func (m *CompapiJobMutation) SetOp(op Op) {
+	m.op = op
+}
+
+// Type returns the node type of this mutation (CompapiJob).
+func (m *CompapiJobMutation) 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 *CompapiJobMutation) Fields() []string {
+	fields := make([]string, 0, 12)
+	if m.created_at != nil {
+		fields = append(fields, compapijob.FieldCreatedAt)
+	}
+	if m.updated_at != nil {
+		fields = append(fields, compapijob.FieldUpdatedAt)
+	}
+	if m.dist_at != nil {
+		fields = append(fields, compapijob.FieldDistAt)
+	}
+	if m.dist_status != nil {
+		fields = append(fields, compapijob.FieldDistStatus)
+	}
+	if m.callback_status != nil {
+		fields = append(fields, compapijob.FieldCallbackStatus)
+	}
+	if m.callback_url != nil {
+		fields = append(fields, compapijob.FieldCallbackURL)
+	}
+	if m.request_json != nil {
+		fields = append(fields, compapijob.FieldRequestJSON)
+	}
+	if m.auth_token != nil {
+		fields = append(fields, compapijob.FieldAuthToken)
+	}
+	if m.event_type != nil {
+		fields = append(fields, compapijob.FieldEventType)
+	}
+	if m.workid_idx != nil {
+		fields = append(fields, compapijob.FieldWorkidIdx)
+	}
+	if m.chat_id != nil {
+		fields = append(fields, compapijob.FieldChatID)
+	}
+	if m.retry_count != nil {
+		fields = append(fields, compapijob.FieldRetryCount)
+	}
+	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 *CompapiJobMutation) Field(name string) (ent.Value, bool) {
+	switch name {
+	case compapijob.FieldCreatedAt:
+		return m.CreatedAt()
+	case compapijob.FieldUpdatedAt:
+		return m.UpdatedAt()
+	case compapijob.FieldDistAt:
+		return m.DistAt()
+	case compapijob.FieldDistStatus:
+		return m.DistStatus()
+	case compapijob.FieldCallbackStatus:
+		return m.CallbackStatus()
+	case compapijob.FieldCallbackURL:
+		return m.CallbackURL()
+	case compapijob.FieldRequestJSON:
+		return m.RequestJSON()
+	case compapijob.FieldAuthToken:
+		return m.AuthToken()
+	case compapijob.FieldEventType:
+		return m.EventType()
+	case compapijob.FieldWorkidIdx:
+		return m.WorkidIdx()
+	case compapijob.FieldChatID:
+		return m.ChatID()
+	case compapijob.FieldRetryCount:
+		return m.RetryCount()
+	}
+	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 *CompapiJobMutation) OldField(ctx context.Context, name string) (ent.Value, error) {
+	switch name {
+	case compapijob.FieldCreatedAt:
+		return m.OldCreatedAt(ctx)
+	case compapijob.FieldUpdatedAt:
+		return m.OldUpdatedAt(ctx)
+	case compapijob.FieldDistAt:
+		return m.OldDistAt(ctx)
+	case compapijob.FieldDistStatus:
+		return m.OldDistStatus(ctx)
+	case compapijob.FieldCallbackStatus:
+		return m.OldCallbackStatus(ctx)
+	case compapijob.FieldCallbackURL:
+		return m.OldCallbackURL(ctx)
+	case compapijob.FieldRequestJSON:
+		return m.OldRequestJSON(ctx)
+	case compapijob.FieldAuthToken:
+		return m.OldAuthToken(ctx)
+	case compapijob.FieldEventType:
+		return m.OldEventType(ctx)
+	case compapijob.FieldWorkidIdx:
+		return m.OldWorkidIdx(ctx)
+	case compapijob.FieldChatID:
+		return m.OldChatID(ctx)
+	case compapijob.FieldRetryCount:
+		return m.OldRetryCount(ctx)
+	}
+	return nil, fmt.Errorf("unknown CompapiJob 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 *CompapiJobMutation) SetField(name string, value ent.Value) error {
+	switch name {
+	case compapijob.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 compapijob.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 compapijob.FieldDistAt:
+		v, ok := value.(time.Time)
+		if !ok {
+			return fmt.Errorf("unexpected type %T for field %s", value, name)
+		}
+		m.SetDistAt(v)
+		return nil
+	case compapijob.FieldDistStatus:
+		v, ok := value.(int8)
+		if !ok {
+			return fmt.Errorf("unexpected type %T for field %s", value, name)
+		}
+		m.SetDistStatus(v)
+		return nil
+	case compapijob.FieldCallbackStatus:
+		v, ok := value.(int8)
+		if !ok {
+			return fmt.Errorf("unexpected type %T for field %s", value, name)
+		}
+		m.SetCallbackStatus(v)
+		return nil
+	case compapijob.FieldCallbackURL:
+		v, ok := value.(string)
+		if !ok {
+			return fmt.Errorf("unexpected type %T for field %s", value, name)
+		}
+		m.SetCallbackURL(v)
+		return nil
+	case compapijob.FieldRequestJSON:
+		v, ok := value.(custom_types.OriginalData)
+		if !ok {
+			return fmt.Errorf("unexpected type %T for field %s", value, name)
+		}
+		m.SetRequestJSON(v)
+		return nil
+	case compapijob.FieldAuthToken:
+		v, ok := value.(string)
+		if !ok {
+			return fmt.Errorf("unexpected type %T for field %s", value, name)
+		}
+		m.SetAuthToken(v)
+		return nil
+	case compapijob.FieldEventType:
+		v, ok := value.(string)
+		if !ok {
+			return fmt.Errorf("unexpected type %T for field %s", value, name)
+		}
+		m.SetEventType(v)
+		return nil
+	case compapijob.FieldWorkidIdx:
+		v, ok := value.(int8)
+		if !ok {
+			return fmt.Errorf("unexpected type %T for field %s", value, name)
+		}
+		m.SetWorkidIdx(v)
+		return nil
+	case compapijob.FieldChatID:
+		v, ok := value.(string)
+		if !ok {
+			return fmt.Errorf("unexpected type %T for field %s", value, name)
+		}
+		m.SetChatID(v)
+		return nil
+	case compapijob.FieldRetryCount:
+		v, ok := value.(int8)
+		if !ok {
+			return fmt.Errorf("unexpected type %T for field %s", value, name)
+		}
+		m.SetRetryCount(v)
+		return nil
+	}
+	return fmt.Errorf("unknown CompapiJob field %s", name)
+}
+
+// AddedFields returns all numeric fields that were incremented/decremented during
+// this mutation.
+func (m *CompapiJobMutation) AddedFields() []string {
+	var fields []string
+	if m.adddist_status != nil {
+		fields = append(fields, compapijob.FieldDistStatus)
+	}
+	if m.addcallback_status != nil {
+		fields = append(fields, compapijob.FieldCallbackStatus)
+	}
+	if m.addworkid_idx != nil {
+		fields = append(fields, compapijob.FieldWorkidIdx)
+	}
+	if m.addretry_count != nil {
+		fields = append(fields, compapijob.FieldRetryCount)
+	}
+	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 *CompapiJobMutation) AddedField(name string) (ent.Value, bool) {
+	switch name {
+	case compapijob.FieldDistStatus:
+		return m.AddedDistStatus()
+	case compapijob.FieldCallbackStatus:
+		return m.AddedCallbackStatus()
+	case compapijob.FieldWorkidIdx:
+		return m.AddedWorkidIdx()
+	case compapijob.FieldRetryCount:
+		return m.AddedRetryCount()
+	}
+	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 *CompapiJobMutation) AddField(name string, value ent.Value) error {
+	switch name {
+	case compapijob.FieldDistStatus:
+		v, ok := value.(int8)
+		if !ok {
+			return fmt.Errorf("unexpected type %T for field %s", value, name)
+		}
+		m.AddDistStatus(v)
+		return nil
+	case compapijob.FieldCallbackStatus:
+		v, ok := value.(int8)
+		if !ok {
+			return fmt.Errorf("unexpected type %T for field %s", value, name)
+		}
+		m.AddCallbackStatus(v)
+		return nil
+	case compapijob.FieldWorkidIdx:
+		v, ok := value.(int8)
+		if !ok {
+			return fmt.Errorf("unexpected type %T for field %s", value, name)
+		}
+		m.AddWorkidIdx(v)
+		return nil
+	case compapijob.FieldRetryCount:
+		v, ok := value.(int8)
+		if !ok {
+			return fmt.Errorf("unexpected type %T for field %s", value, name)
+		}
+		m.AddRetryCount(v)
+		return nil
+	}
+	return fmt.Errorf("unknown CompapiJob numeric field %s", name)
+}
+
+// ClearedFields returns all nullable fields that were cleared during this
+// mutation.
+func (m *CompapiJobMutation) ClearedFields() []string {
+	var fields []string
+	if m.FieldCleared(compapijob.FieldDistAt) {
+		fields = append(fields, compapijob.FieldDistAt)
+	}
+	if m.FieldCleared(compapijob.FieldDistStatus) {
+		fields = append(fields, compapijob.FieldDistStatus)
+	}
+	if m.FieldCleared(compapijob.FieldCallbackStatus) {
+		fields = append(fields, compapijob.FieldCallbackStatus)
+	}
+	if m.FieldCleared(compapijob.FieldWorkidIdx) {
+		fields = append(fields, compapijob.FieldWorkidIdx)
+	}
+	if m.FieldCleared(compapijob.FieldChatID) {
+		fields = append(fields, compapijob.FieldChatID)
+	}
+	if m.FieldCleared(compapijob.FieldRetryCount) {
+		fields = append(fields, compapijob.FieldRetryCount)
+	}
+	return fields
+}
+
+// FieldCleared returns a boolean indicating if a field with the given name was
+// cleared in this mutation.
+func (m *CompapiJobMutation) 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 *CompapiJobMutation) ClearField(name string) error {
+	switch name {
+	case compapijob.FieldDistAt:
+		m.ClearDistAt()
+		return nil
+	case compapijob.FieldDistStatus:
+		m.ClearDistStatus()
+		return nil
+	case compapijob.FieldCallbackStatus:
+		m.ClearCallbackStatus()
+		return nil
+	case compapijob.FieldWorkidIdx:
+		m.ClearWorkidIdx()
+		return nil
+	case compapijob.FieldChatID:
+		m.ClearChatID()
+		return nil
+	case compapijob.FieldRetryCount:
+		m.ClearRetryCount()
+		return nil
+	}
+	return fmt.Errorf("unknown CompapiJob 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 *CompapiJobMutation) ResetField(name string) error {
+	switch name {
+	case compapijob.FieldCreatedAt:
+		m.ResetCreatedAt()
+		return nil
+	case compapijob.FieldUpdatedAt:
+		m.ResetUpdatedAt()
+		return nil
+	case compapijob.FieldDistAt:
+		m.ResetDistAt()
+		return nil
+	case compapijob.FieldDistStatus:
+		m.ResetDistStatus()
+		return nil
+	case compapijob.FieldCallbackStatus:
+		m.ResetCallbackStatus()
+		return nil
+	case compapijob.FieldCallbackURL:
+		m.ResetCallbackURL()
+		return nil
+	case compapijob.FieldRequestJSON:
+		m.ResetRequestJSON()
+		return nil
+	case compapijob.FieldAuthToken:
+		m.ResetAuthToken()
+		return nil
+	case compapijob.FieldEventType:
+		m.ResetEventType()
+		return nil
+	case compapijob.FieldWorkidIdx:
+		m.ResetWorkidIdx()
+		return nil
+	case compapijob.FieldChatID:
+		m.ResetChatID()
+		return nil
+	case compapijob.FieldRetryCount:
+		m.ResetRetryCount()
+		return nil
+	}
+	return fmt.Errorf("unknown CompapiJob field %s", name)
+}
+
+// AddedEdges returns all edge names that were set/added in this mutation.
+func (m *CompapiJobMutation) 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 *CompapiJobMutation) AddedIDs(name string) []ent.Value {
+	return nil
+}
+
+// RemovedEdges returns all edge names that were removed in this mutation.
+func (m *CompapiJobMutation) 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 *CompapiJobMutation) RemovedIDs(name string) []ent.Value {
+	return nil
+}
+
+// ClearedEdges returns all edge names that were cleared in this mutation.
+func (m *CompapiJobMutation) 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 *CompapiJobMutation) 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 *CompapiJobMutation) ClearEdge(name string) error {
+	return fmt.Errorf("unknown CompapiJob 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 *CompapiJobMutation) ResetEdge(name string) error {
+	return fmt.Errorf("unknown CompapiJob edge %s", name)
+}
+
 // ContactMutation represents an operation that mutates the Contact nodes in the graph.
 type ContactMutation struct {
 	config

+ 82 - 0
ent/pagination.go

@@ -14,6 +14,7 @@ import (
 	"wechat-api/ent/category"
 	"wechat-api/ent/chatrecords"
 	"wechat-api/ent/chatsession"
+	"wechat-api/ent/compapijob"
 	"wechat-api/ent/contact"
 	"wechat-api/ent/creditbalance"
 	"wechat-api/ent/creditusage"
@@ -823,6 +824,87 @@ func (cs *ChatSessionQuery) Page(
 	return ret, nil
 }
 
+type CompapiJobPager struct {
+	Order  compapijob.OrderOption
+	Filter func(*CompapiJobQuery) (*CompapiJobQuery, error)
+}
+
+// CompapiJobPaginateOption enables pagination customization.
+type CompapiJobPaginateOption func(*CompapiJobPager)
+
+// DefaultCompapiJobOrder is the default ordering of CompapiJob.
+var DefaultCompapiJobOrder = Desc(compapijob.FieldID)
+
+func newCompapiJobPager(opts []CompapiJobPaginateOption) (*CompapiJobPager, error) {
+	pager := &CompapiJobPager{}
+	for _, opt := range opts {
+		opt(pager)
+	}
+	if pager.Order == nil {
+		pager.Order = DefaultCompapiJobOrder
+	}
+	return pager, nil
+}
+
+func (p *CompapiJobPager) ApplyFilter(query *CompapiJobQuery) (*CompapiJobQuery, error) {
+	if p.Filter != nil {
+		return p.Filter(query)
+	}
+	return query, nil
+}
+
+// CompapiJobPageList is CompapiJob PageList result.
+type CompapiJobPageList struct {
+	List        []*CompapiJob `json:"list"`
+	PageDetails *PageDetails  `json:"pageDetails"`
+}
+
+func (cj *CompapiJobQuery) Page(
+	ctx context.Context, pageNum uint64, pageSize uint64, opts ...CompapiJobPaginateOption,
+) (*CompapiJobPageList, error) {
+
+	pager, err := newCompapiJobPager(opts)
+	if err != nil {
+		return nil, err
+	}
+
+	if cj, err = pager.ApplyFilter(cj); err != nil {
+		return nil, err
+	}
+
+	ret := &CompapiJobPageList{}
+
+	ret.PageDetails = &PageDetails{
+		Page: pageNum,
+		Size: pageSize,
+	}
+
+	query := cj.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 {
+		cj = cj.Order(pager.Order)
+	} else {
+		cj = cj.Order(DefaultCompapiJobOrder)
+	}
+
+	cj = cj.Offset(int((pageNum - 1) * pageSize)).Limit(int(pageSize))
+	list, err := cj.All(ctx)
+	if err != nil {
+		return nil, err
+	}
+	ret.List = list
+
+	return ret, nil
+}
+
 type ContactPager struct {
 	Order  contact.OrderOption
 	Filter func(*ContactQuery) (*ContactQuery, error)

+ 3 - 0
ent/predicate/predicate.go

@@ -33,6 +33,9 @@ type ChatRecords func(*sql.Selector)
 // ChatSession is the predicate function for chatsession builders.
 type ChatSession func(*sql.Selector)
 
+// CompapiJob is the predicate function for compapijob builders.
+type CompapiJob func(*sql.Selector)
+
 // Contact is the predicate function for contact builders.
 type Contact func(*sql.Selector)
 

+ 44 - 0
ent/runtime/runtime.go

@@ -13,6 +13,7 @@ import (
 	"wechat-api/ent/category"
 	"wechat-api/ent/chatrecords"
 	"wechat-api/ent/chatsession"
+	"wechat-api/ent/compapijob"
 	"wechat-api/ent/contact"
 	"wechat-api/ent/creditbalance"
 	"wechat-api/ent/creditusage"
@@ -378,6 +379,49 @@ func init() {
 	chatsessionDescBotType := chatsessionFields[3].Descriptor()
 	// chatsession.DefaultBotType holds the default value on creation for the bot_type field.
 	chatsession.DefaultBotType = chatsessionDescBotType.Default.(uint8)
+	compapijobMixin := schema.CompapiJob{}.Mixin()
+	compapijobMixinFields0 := compapijobMixin[0].Fields()
+	_ = compapijobMixinFields0
+	compapijobFields := schema.CompapiJob{}.Fields()
+	_ = compapijobFields
+	// compapijobDescCreatedAt is the schema descriptor for created_at field.
+	compapijobDescCreatedAt := compapijobMixinFields0[1].Descriptor()
+	// compapijob.DefaultCreatedAt holds the default value on creation for the created_at field.
+	compapijob.DefaultCreatedAt = compapijobDescCreatedAt.Default.(func() time.Time)
+	// compapijobDescUpdatedAt is the schema descriptor for updated_at field.
+	compapijobDescUpdatedAt := compapijobMixinFields0[2].Descriptor()
+	// compapijob.DefaultUpdatedAt holds the default value on creation for the updated_at field.
+	compapijob.DefaultUpdatedAt = compapijobDescUpdatedAt.Default.(func() time.Time)
+	// compapijob.UpdateDefaultUpdatedAt holds the default value on update for the updated_at field.
+	compapijob.UpdateDefaultUpdatedAt = compapijobDescUpdatedAt.UpdateDefault.(func() time.Time)
+	// compapijobDescDistStatus is the schema descriptor for dist_status field.
+	compapijobDescDistStatus := compapijobFields[1].Descriptor()
+	// compapijob.DefaultDistStatus holds the default value on creation for the dist_status field.
+	compapijob.DefaultDistStatus = compapijobDescDistStatus.Default.(int8)
+	// compapijobDescCallbackStatus is the schema descriptor for callback_status field.
+	compapijobDescCallbackStatus := compapijobFields[2].Descriptor()
+	// compapijob.DefaultCallbackStatus holds the default value on creation for the callback_status field.
+	compapijob.DefaultCallbackStatus = compapijobDescCallbackStatus.Default.(int8)
+	// compapijobDescAuthToken is the schema descriptor for auth_token field.
+	compapijobDescAuthToken := compapijobFields[5].Descriptor()
+	// compapijob.DefaultAuthToken holds the default value on creation for the auth_token field.
+	compapijob.DefaultAuthToken = compapijobDescAuthToken.Default.(string)
+	// compapijobDescEventType is the schema descriptor for event_type field.
+	compapijobDescEventType := compapijobFields[6].Descriptor()
+	// compapijob.DefaultEventType holds the default value on creation for the event_type field.
+	compapijob.DefaultEventType = compapijobDescEventType.Default.(string)
+	// compapijobDescWorkidIdx is the schema descriptor for workid_idx field.
+	compapijobDescWorkidIdx := compapijobFields[7].Descriptor()
+	// compapijob.DefaultWorkidIdx holds the default value on creation for the workid_idx field.
+	compapijob.DefaultWorkidIdx = compapijobDescWorkidIdx.Default.(int8)
+	// compapijobDescChatID is the schema descriptor for chat_id field.
+	compapijobDescChatID := compapijobFields[8].Descriptor()
+	// compapijob.DefaultChatID holds the default value on creation for the chat_id field.
+	compapijob.DefaultChatID = compapijobDescChatID.Default.(string)
+	// compapijobDescRetryCount is the schema descriptor for retry_count field.
+	compapijobDescRetryCount := compapijobFields[9].Descriptor()
+	// compapijob.DefaultRetryCount holds the default value on creation for the retry_count field.
+	compapijob.DefaultRetryCount = compapijobDescRetryCount.Default.(int8)
 	contactMixin := schema.Contact{}.Mixin()
 	contactMixinHooks2 := contactMixin[2].Hooks()
 	contact.Hooks[0] = contactMixinHooks2[0]

+ 56 - 0
ent/schema/compapi_job.go

@@ -0,0 +1,56 @@
+package schema
+
+import (
+	"wechat-api/ent/custom_types"
+
+	"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"
+)
+
+// CompapiJob holds the schema definition for the CompapiJob entity.
+type CompapiJob struct {
+	ent.Schema
+}
+
+// Fields of the CompapiJob.
+func (CompapiJob) Fields() []ent.Field {
+
+	return []ent.Field{
+		field.Time("dist_at").Optional().Annotations(entsql.WithComments(true)).Comment("Dist Time | 分发时间"),
+		field.Int8("dist_status").Optional().Default(0).Annotations(entsql.WithComments(true)).Comment("dist status | 分发状态 0 未 1 已"),
+		field.Int8("callback_status").Optional().Default(10).Annotations(entsql.WithComments(true)).Comment("callback_status | 回调状态 10 准备回调 20 "),
+		field.String("callback_url").Annotations(entsql.WithComments(true)).Comment("异步执行回调地址"),
+		field.JSON("request_json", custom_types.OriginalData{}).Annotations(entsql.WithComments(true)).Comment("请求参数结构JSON"),
+		field.String("auth_token").Default("").Annotations(entsql.WithComments(true)).Comment("发起请求者的授权token"),
+		field.String("event_type").Default("").Annotations(entsql.WithComments(true)).Comment("发起请求者的类型"),
+		field.Int8("workid_idx").Optional().Default(0).Annotations(entsql.WithComments(true)).Comment("workId在字典中的索引"),
+		field.String("chat_id").Optional().Default("").Annotations(entsql.WithComments(true)).Comment("会话ID"),
+		field.Int8("retry_count").Optional().Default(0).Annotations(entsql.WithComments(true)).Comment("retry count | 重试次数"),
+	}
+}
+
+func (CompapiJob) Mixin() []ent.Mixin {
+	return []ent.Mixin{
+		mixins.IDMixin{},
+	}
+}
+
+func (CompapiJob) Indexes() []ent.Index {
+	return []ent.Index{
+		index.Fields("dist_status"),
+		index.Fields("callback_status"),
+	}
+}
+
+func (CompapiJob) Edges() []ent.Edge { return []ent.Edge{} }
+
+func (CompapiJob) Annotations() []schema.Annotation {
+	return []schema.Annotation{
+		entsql.WithComments(true),
+		entsql.Annotation{Table: "compapi_job"},
+	}
+}

+ 264 - 0
ent/set_not_nil.go

@@ -2096,6 +2096,270 @@ func (cs *ChatSessionCreate) SetNotNilBotType(value *uint8) *ChatSessionCreate {
 }
 
 // set field if value's pointer is not nil.
+func (cj *CompapiJobUpdate) SetNotNilUpdatedAt(value *time.Time) *CompapiJobUpdate {
+	if value != nil {
+		return cj.SetUpdatedAt(*value)
+	}
+	return cj
+}
+
+// set field if value's pointer is not nil.
+func (cj *CompapiJobUpdateOne) SetNotNilUpdatedAt(value *time.Time) *CompapiJobUpdateOne {
+	if value != nil {
+		return cj.SetUpdatedAt(*value)
+	}
+	return cj
+}
+
+// set field if value's pointer is not nil.
+func (cj *CompapiJobCreate) SetNotNilUpdatedAt(value *time.Time) *CompapiJobCreate {
+	if value != nil {
+		return cj.SetUpdatedAt(*value)
+	}
+	return cj
+}
+
+// set field if value's pointer is not nil.
+func (cj *CompapiJobUpdate) SetNotNilDistAt(value *time.Time) *CompapiJobUpdate {
+	if value != nil {
+		return cj.SetDistAt(*value)
+	}
+	return cj
+}
+
+// set field if value's pointer is not nil.
+func (cj *CompapiJobUpdateOne) SetNotNilDistAt(value *time.Time) *CompapiJobUpdateOne {
+	if value != nil {
+		return cj.SetDistAt(*value)
+	}
+	return cj
+}
+
+// set field if value's pointer is not nil.
+func (cj *CompapiJobCreate) SetNotNilDistAt(value *time.Time) *CompapiJobCreate {
+	if value != nil {
+		return cj.SetDistAt(*value)
+	}
+	return cj
+}
+
+// set field if value's pointer is not nil.
+func (cj *CompapiJobUpdate) SetNotNilDistStatus(value *int8) *CompapiJobUpdate {
+	if value != nil {
+		return cj.SetDistStatus(*value)
+	}
+	return cj
+}
+
+// set field if value's pointer is not nil.
+func (cj *CompapiJobUpdateOne) SetNotNilDistStatus(value *int8) *CompapiJobUpdateOne {
+	if value != nil {
+		return cj.SetDistStatus(*value)
+	}
+	return cj
+}
+
+// set field if value's pointer is not nil.
+func (cj *CompapiJobCreate) SetNotNilDistStatus(value *int8) *CompapiJobCreate {
+	if value != nil {
+		return cj.SetDistStatus(*value)
+	}
+	return cj
+}
+
+// set field if value's pointer is not nil.
+func (cj *CompapiJobUpdate) SetNotNilCallbackStatus(value *int8) *CompapiJobUpdate {
+	if value != nil {
+		return cj.SetCallbackStatus(*value)
+	}
+	return cj
+}
+
+// set field if value's pointer is not nil.
+func (cj *CompapiJobUpdateOne) SetNotNilCallbackStatus(value *int8) *CompapiJobUpdateOne {
+	if value != nil {
+		return cj.SetCallbackStatus(*value)
+	}
+	return cj
+}
+
+// set field if value's pointer is not nil.
+func (cj *CompapiJobCreate) SetNotNilCallbackStatus(value *int8) *CompapiJobCreate {
+	if value != nil {
+		return cj.SetCallbackStatus(*value)
+	}
+	return cj
+}
+
+// set field if value's pointer is not nil.
+func (cj *CompapiJobUpdate) SetNotNilCallbackURL(value *string) *CompapiJobUpdate {
+	if value != nil {
+		return cj.SetCallbackURL(*value)
+	}
+	return cj
+}
+
+// set field if value's pointer is not nil.
+func (cj *CompapiJobUpdateOne) SetNotNilCallbackURL(value *string) *CompapiJobUpdateOne {
+	if value != nil {
+		return cj.SetCallbackURL(*value)
+	}
+	return cj
+}
+
+// set field if value's pointer is not nil.
+func (cj *CompapiJobCreate) SetNotNilCallbackURL(value *string) *CompapiJobCreate {
+	if value != nil {
+		return cj.SetCallbackURL(*value)
+	}
+	return cj
+}
+
+// set field if value's pointer is not nil.
+func (cj *CompapiJobUpdate) SetNotNilRequestJSON(value *custom_types.OriginalData) *CompapiJobUpdate {
+	if value != nil {
+		return cj.SetRequestJSON(*value)
+	}
+	return cj
+}
+
+// set field if value's pointer is not nil.
+func (cj *CompapiJobUpdateOne) SetNotNilRequestJSON(value *custom_types.OriginalData) *CompapiJobUpdateOne {
+	if value != nil {
+		return cj.SetRequestJSON(*value)
+	}
+	return cj
+}
+
+// set field if value's pointer is not nil.
+func (cj *CompapiJobCreate) SetNotNilRequestJSON(value *custom_types.OriginalData) *CompapiJobCreate {
+	if value != nil {
+		return cj.SetRequestJSON(*value)
+	}
+	return cj
+}
+
+// set field if value's pointer is not nil.
+func (cj *CompapiJobUpdate) SetNotNilAuthToken(value *string) *CompapiJobUpdate {
+	if value != nil {
+		return cj.SetAuthToken(*value)
+	}
+	return cj
+}
+
+// set field if value's pointer is not nil.
+func (cj *CompapiJobUpdateOne) SetNotNilAuthToken(value *string) *CompapiJobUpdateOne {
+	if value != nil {
+		return cj.SetAuthToken(*value)
+	}
+	return cj
+}
+
+// set field if value's pointer is not nil.
+func (cj *CompapiJobCreate) SetNotNilAuthToken(value *string) *CompapiJobCreate {
+	if value != nil {
+		return cj.SetAuthToken(*value)
+	}
+	return cj
+}
+
+// set field if value's pointer is not nil.
+func (cj *CompapiJobUpdate) SetNotNilEventType(value *string) *CompapiJobUpdate {
+	if value != nil {
+		return cj.SetEventType(*value)
+	}
+	return cj
+}
+
+// set field if value's pointer is not nil.
+func (cj *CompapiJobUpdateOne) SetNotNilEventType(value *string) *CompapiJobUpdateOne {
+	if value != nil {
+		return cj.SetEventType(*value)
+	}
+	return cj
+}
+
+// set field if value's pointer is not nil.
+func (cj *CompapiJobCreate) SetNotNilEventType(value *string) *CompapiJobCreate {
+	if value != nil {
+		return cj.SetEventType(*value)
+	}
+	return cj
+}
+
+// set field if value's pointer is not nil.
+func (cj *CompapiJobUpdate) SetNotNilWorkidIdx(value *int8) *CompapiJobUpdate {
+	if value != nil {
+		return cj.SetWorkidIdx(*value)
+	}
+	return cj
+}
+
+// set field if value's pointer is not nil.
+func (cj *CompapiJobUpdateOne) SetNotNilWorkidIdx(value *int8) *CompapiJobUpdateOne {
+	if value != nil {
+		return cj.SetWorkidIdx(*value)
+	}
+	return cj
+}
+
+// set field if value's pointer is not nil.
+func (cj *CompapiJobCreate) SetNotNilWorkidIdx(value *int8) *CompapiJobCreate {
+	if value != nil {
+		return cj.SetWorkidIdx(*value)
+	}
+	return cj
+}
+
+// set field if value's pointer is not nil.
+func (cj *CompapiJobUpdate) SetNotNilChatID(value *string) *CompapiJobUpdate {
+	if value != nil {
+		return cj.SetChatID(*value)
+	}
+	return cj
+}
+
+// set field if value's pointer is not nil.
+func (cj *CompapiJobUpdateOne) SetNotNilChatID(value *string) *CompapiJobUpdateOne {
+	if value != nil {
+		return cj.SetChatID(*value)
+	}
+	return cj
+}
+
+// set field if value's pointer is not nil.
+func (cj *CompapiJobCreate) SetNotNilChatID(value *string) *CompapiJobCreate {
+	if value != nil {
+		return cj.SetChatID(*value)
+	}
+	return cj
+}
+
+// set field if value's pointer is not nil.
+func (cj *CompapiJobUpdate) SetNotNilRetryCount(value *int8) *CompapiJobUpdate {
+	if value != nil {
+		return cj.SetRetryCount(*value)
+	}
+	return cj
+}
+
+// set field if value's pointer is not nil.
+func (cj *CompapiJobUpdateOne) SetNotNilRetryCount(value *int8) *CompapiJobUpdateOne {
+	if value != nil {
+		return cj.SetRetryCount(*value)
+	}
+	return cj
+}
+
+// set field if value's pointer is not nil.
+func (cj *CompapiJobCreate) SetNotNilRetryCount(value *int8) *CompapiJobCreate {
+	if value != nil {
+		return cj.SetRetryCount(*value)
+	}
+	return cj
+}
+
+// set field if value's pointer is not nil.
 func (c *ContactUpdate) SetNotNilUpdatedAt(value *time.Time) *ContactUpdate {
 	if value != nil {
 		return c.SetUpdatedAt(*value)

+ 3 - 0
ent/tx.go

@@ -32,6 +32,8 @@ type Tx struct {
 	ChatRecords *ChatRecordsClient
 	// ChatSession is the client for interacting with the ChatSession builders.
 	ChatSession *ChatSessionClient
+	// CompapiJob is the client for interacting with the CompapiJob builders.
+	CompapiJob *CompapiJobClient
 	// Contact is the client for interacting with the Contact builders.
 	Contact *ContactClient
 	// CreditBalance is the client for interacting with the CreditBalance builders.
@@ -236,6 +238,7 @@ func (tx *Tx) init() {
 	tx.Category = NewCategoryClient(tx.config)
 	tx.ChatRecords = NewChatRecordsClient(tx.config)
 	tx.ChatSession = NewChatSessionClient(tx.config)
+	tx.CompapiJob = NewCompapiJobClient(tx.config)
 	tx.Contact = NewContactClient(tx.config)
 	tx.CreditBalance = NewCreditBalanceClient(tx.config)
 	tx.CreditUsage = NewCreditUsageClient(tx.config)

+ 10 - 16
internal/handler/chat/chat_completions_handler.go

@@ -3,7 +3,6 @@ package chat
 import (
 	"bytes"
 	"encoding/json"
-	"fmt"
 	"io"
 	"net/http"
 
@@ -33,21 +32,14 @@ import (
 
 func ChatCompletionsHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
 	return func(w http.ResponseWriter, r *http.Request) {
+		var req types.CompApiReq
 		/*
-			var req types.CompApiReq
 			if err := httpx.Parse(r, &req, true); err != nil {
 				httpx.ErrorCtx(r.Context(), w, err)
 				return
 			}
-
-			l := chat.NewChatCompletionsLogic(r.Context(), svcCtx)
-			resp, err := l.ChatCompletions(&req)
-			if err != nil {
-				httpx.ErrorCtx(r.Context(), w, err)
-			} else {
-				httpx.OkJsonCtx(r.Context(), w, resp)
-			}
 		*/
+
 		// 读取请求体
 		body, err := io.ReadAll(r.Body)
 		if err != nil {
@@ -56,23 +48,25 @@ func ChatCompletionsHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
 		}
 		// 将请求体还原,以便后续处理
 		r.Body = io.NopCloser(bytes.NewBuffer(body))
-
-		// 打印请求体
 		logx.Info(string(body))
-		var req types.CompApiReq
 		err = json.Unmarshal([]byte(string(body)), &req)
 		if err != nil {
-			fmt.Println("Error:", err)
+			httpx.ErrorCtx(r.Context(), w, err)
 			return
 		}
 		// 打印请求体
 		logx.Info(req)
+
 		l := chat.NewChatCompletionsLogic(r.Context(), svcCtx)
-		resp, err := l.ChatCompletions(&req)
+		am, resp, err := l.ChatCompletions(&req)
 		if err != nil {
 			httpx.ErrorCtx(r.Context(), w, err)
 		} else {
-			httpx.OkJsonCtx(r.Context(), w, resp)
+			if !am {
+				httpx.OkJsonCtx(r.Context(), w, resp)
+			} else {
+				httpx.OkJsonCtx(r.Context(), w, types.BaseDataInfo{Code: 0, Msg: "请求已经受理"})
+			}
 		}
 	}
 }

+ 171 - 33
internal/logic/chat/chat_completions_logic.go

@@ -3,13 +3,20 @@ package chat
 import (
 	"context"
 	"errors"
+	"fmt"
+	"net"
+	"net/url"
 	"strconv"
+	"strings"
+	"time"
+	"unicode"
 
 	"wechat-api/ent"
 	"wechat-api/internal/svc"
 	"wechat-api/internal/types"
 	"wechat-api/internal/utils/compapi"
 	"wechat-api/internal/utils/contextkey"
+	"wechat-api/internal/utils/typekit"
 
 	"wechat-api/ent/custom_types"
 	"wechat-api/ent/predicate"
@@ -32,7 +39,7 @@ func NewChatCompletionsLogic(ctx context.Context, svcCtx *svc.ServiceContext) *C
 		svcCtx: svcCtx}
 }
 
-func (l *ChatCompletionsLogic) ChatCompletions(req *types.CompApiReq) (resp *types.CompOpenApiResp, err error) {
+func (l *ChatCompletionsLogic) ChatCompletions(req *types.CompApiReq) (asyncMode bool, resp *types.CompOpenApiResp, err error) {
 	// todo: add your logic here and delete this line
 
 	/*
@@ -44,40 +51,68 @@ func (l *ChatCompletionsLogic) ChatCompletions(req *types.CompApiReq) (resp *typ
 		apiKeyObj *ent.ApiKey
 		ok        bool
 	)
-	workToken := compapi.GetWorkTokenByID(req.EventType, req.WorkId)
+	asyncMode = false
+
+	//微调部分请求参数
+	reqAdjust(req)
+
+	//从上下文中获取鉴权中间件埋下的apiAuthInfo
 	apiKeyObj, ok = contextkey.AuthTokenInfoKey.GetValue(l.ctx)
 	if !ok {
-		return nil, errors.New("content get token err")
-	}
-	/*
-		fmt.Println("=========================================")
-		fmt.Printf("In ChatCompletion Get Token Info:\nKey:'%s'\n", apiKeyObj.Key)
-		fmt.Printf("Title:'%s'\n", apiKeyObj.Title)
-		fmt.Printf("OpenaiBase:'%s'\n", apiKeyObj.OpenaiBase)
-		fmt.Printf("OpenaiKey:'%s'\n", apiKeyObj.OpenaiKey)
-		fmt.Printf("workToken:'%s' because %s/%s\n", workToken, req.EventType, req.WorkId)
-		fmt.Println("=========================================")
-	*/
-
-	if len(apiKeyObj.OpenaiBase) == 0 || len(workToken) == 0 {
-		return nil, errors.New("not auth info")
+		return asyncMode, nil, errors.New("content get auth info err")
 	}
 
-	apiResp, err := l.workForFastgpt(req, workToken, apiKeyObj.OpenaiBase)
-	if err == nil && apiResp != nil {
-		l.doRequestLog(req, apiResp) //请求记录
+	//微调apiKeyObj的openaikey
+	apiKeyObjAdjust(req.EventType, req.WorkId, apiKeyObj)
+
+	apiKeyObj.CreatedAt = time.Now()
+	fmt.Println(typekit.PrettyPrint(apiKeyObj))
+
+	fmt.Println("=========================================")
+	fmt.Printf("In ChatCompletion Get Token Info:\nKey:'%s'\n", apiKeyObj.Key)
+	fmt.Printf("Title:'%s'\n", apiKeyObj.Title)
+	fmt.Printf("OpenaiBase:'%s'\n", apiKeyObj.OpenaiBase)
+	fmt.Printf("OpenaiKey:'%s'\n", apiKeyObj.OpenaiKey)
+	fmt.Printf("workToken:'%s' because %s/%s\n", apiKeyObj.OpenaiKey, req.EventType, req.WorkId)
+	fmt.Printf("req.ChatId:'%s VS req.FastgptChatId:'%s'\n", req.ChatId, req.FastgptChatId)
+	fmt.Printf("apiKeyObj.CreatedAt:'%v' || apiKeyObj.UpdatedAt:'%v'\n", apiKeyObj.CreatedAt, apiKeyObj.UpdatedAt)
+	fmt.Println("=========================================")
+
+	if isAsyncReqest(req) { //异步请求处理模式
+		fmt.Println("~~~~~~~~~~~~~~~~~~~isAsyncReqest:", req.Callback)
+		asyncMode = true
+		err = l.appendAsyncRequest(apiKeyObj, req)
+	} else { //同步请求处理模式
+		fmt.Println("~~~~~~~~~~~~~~~~~~~isSyncReqest")
+		resp, err = l.workForFastgpt(apiKeyObj, req)
+		if err == nil && resp != nil {
+			l.doSyncRequestLog(apiKeyObj, req, resp) //请求记录
+		}
 	}
-
-	return apiResp, err
+	return asyncMode, resp, err
 }
 
-func (l *ChatCompletionsLogic) doRequestLog(req *types.CompApiReq, resp *types.CompOpenApiResp) error {
-	authToken, ok := contextkey.OpenapiTokenKey.GetValue(l.ctx)
-	if !ok {
-		return errors.New("content get auth token err")
+func (l *ChatCompletionsLogic) appendAsyncRequest(apiKeyObj *ent.ApiKey, req *types.CompApiReq) error {
+
+	workIDIdx := int8(compapi.GetWorkIdxByID(req.EventType, req.WorkId))
+	rawReqResp := custom_types.OriginalData{Request: req}
+	res, err := l.svcCtx.DB.CompapiJob.Create().
+		SetNotNilCallbackURL(&req.Callback).
+		SetNotNilAuthToken(&apiKeyObj.Key).
+		SetNotNilEventType(&req.EventType).
+		SetNillableWorkidIdx(&workIDIdx).
+		SetNotNilRequestJSON(&rawReqResp).
+		SetNillableChatID(&req.ChatId).
+		Save(l.ctx)
+
+	if err == nil {
+		logx.Infof("appendAsyncRequest succ,get id:%d", res.ID)
 	}
+	return err
+}
 
-	return l.appendUsageDetailLog(authToken, req, resp)
+func (l *ChatCompletionsLogic) doSyncRequestLog(obj *ent.ApiKey, req *types.CompApiReq, resp *types.CompOpenApiResp) error {
+	return l.appendUsageDetailLog(obj.Key, req, resp)
 }
 
 func (l *ChatCompletionsLogic) getUsagetotalIdByToken(authToken string) (uint64, error) {
@@ -148,9 +183,8 @@ func (l *ChatCompletionsLogic) sumTotalTokensByAuthToken(authToken string) (uint
 func (l *ChatCompletionsLogic) appendUsageDetailLog(authToken string, req *types.CompApiReq, resp *types.CompOpenApiResp) error {
 
 	logType := 5
-	workIdx := compapi.GetWorkIdxByID(req.EventType, req.WorkId)
+	workIdx := int(compapi.GetWorkIdxByID(req.EventType, req.WorkId))
 	rawReqResp := custom_types.OriginalData{Request: req, Response: resp}
-
 	tmpId := 0
 	tmpId, _ = strconv.Atoi(resp.ID)
 	sessionId := uint64(tmpId)
@@ -183,7 +217,6 @@ func (l *ChatCompletionsLogic) appendUsageDetailLog(authToken string, req *types
 		SetNotNilReceiverID(&req.EventType).
 		SetNotNilSessionID(&sessionId).
 		SetNillableApp(&workIdx).
-		//SetNillableRequest(&req.Messages[0].Content).
 		SetNillableRequest(&msgContent).
 		SetNillableResponse(&resp.Choices[0].Message.Content).
 		SetNillableOrganizationID(&orgId).
@@ -199,11 +232,16 @@ func (l *ChatCompletionsLogic) appendUsageDetailLog(authToken string, req *types
 	return err
 }
 
-func (l *ChatCompletionsLogic) workForFastgpt(req *types.CompApiReq, apiKey string, apiBase string) (resp *types.CompOpenApiResp, err error) {
+func (l *ChatCompletionsLogic) workForFastgpt(apiKeyObj *ent.ApiKey, req *types.CompApiReq) (resp *types.CompOpenApiResp, err error) {
 
 	//apiKey := "fastgpt-d2uehCb2T40h9chNGjf4bpFrVKmMkCFPbrjfVLZ6DAL2zzqzOFJWP"
-	if len(req.ChatId) > 0 && len(req.FastgptChatId) == 0 {
-		req.FastgptChatId = req.ChatId
+	return compapi.NewFastgptChatCompletions(l.ctx, apiKeyObj.OpenaiKey, apiKeyObj.OpenaiBase, req)
+
+}
+
+func reqAdjust(req *types.CompApiReq) {
+	if req.EventType != "fastgpt" {
+		return
 	}
 	if len(req.Model) > 0 {
 		if req.Variables == nil {
@@ -211,6 +249,106 @@ func (l *ChatCompletionsLogic) workForFastgpt(req *types.CompApiReq, apiKey stri
 		}
 		req.Variables["model"] = req.Model
 	}
-	return compapi.NewFastgptChatCompletions(l.ctx, apiKey, apiBase, req)
 
+	if len(req.ChatId) > 0 && len(req.FastgptChatId) == 0 {
+		req.FastgptChatId = req.ChatId
+	} else if len(req.ChatId) == 0 && len(req.FastgptChatId) > 0 {
+		req.ChatId = req.FastgptChatId
+	}
+
+}
+
+func apiKeyObjAdjust(eventType string, workId string, obj *ent.ApiKey) {
+	if eventType != "fastgpt" {
+		return
+	}
+	obj.OpenaiKey, _ = compapi.GetWorkInfoByID(eventType, workId)
+}
+
+func IsValidURL(s string) bool {
+	// 阶段1:快速预检
+	if len(s) < 10 || len(s) > 2048 { // 常见URL长度范围
+		return false
+	}
+
+	// 阶段2:标准库解析
+	u, err := url.Parse(s)
+	if err != nil || u.Scheme == "" || u.Host == "" {
+		return false
+	}
+
+	// 阶段3:协议校验(支持常见网络协议)
+	switch u.Scheme {
+	case "http", "https", "ftp", "ftps", "sftp":
+		// 允许的协议类型
+	default:
+		return false
+	}
+
+	// 阶段4:主机名深度校验
+	host := u.Hostname()
+	if strings.Contains(host, "..") || strings.ContainsAny(host, "!#$%&'()*,:;<=>?[]^`{|}~") {
+		return false
+	}
+
+	// IPv4/IPv6 校验
+	if ip := net.ParseIP(host); ip != nil {
+		return true // 有效IP地址
+	}
+
+	// 域名格式校验
+	if !isValidDomain(host) {
+		return false
+	}
+
+	// 阶段5:端口校验(可选)
+	if port := u.Port(); port != "" {
+		for _, r := range port {
+			if !unicode.IsDigit(r) {
+				return false
+			}
+		}
+		if len(port) > 5 || port == "0" {
+			return false
+		}
+	}
+
+	return true
+}
+
+// 高性能域名校验 (支持国际化域名IDNA)
+func isValidDomain(host string) bool {
+	// 快速排除非法字符
+	if strings.ContainsAny(host, " _+/\\") {
+		return false
+	}
+
+	// 分段检查
+	labels := strings.Split(host, ".")
+	if len(labels) < 2 { // 至少包含顶级域和二级域
+		return false
+	}
+
+	for _, label := range labels {
+		if len(label) < 1 || len(label) > 63 {
+			return false
+		}
+		if label[0] == '-' || label[len(label)-1] == '-' {
+			return false
+		}
+	}
+
+	// 最终DNS格式校验
+	if _, err := net.LookupHost(host); err == nil {
+		return true // 实际DNS解析验证(根据需求开启)
+	}
+
+	return true // 若不需要实际解析可始终返回true
+}
+
+func isAsyncReqest(req *types.CompApiReq) bool {
+	if !req.IsBatch || !IsValidURL(req.Callback) {
+		return false
+	}
+	return true
 }

+ 5 - 1
internal/middleware/openauthority_middleware.go

@@ -138,8 +138,12 @@ func (m *OpenAuthorityMiddleware) Handle(next http.HandlerFunc) http.HandlerFunc
 			httpx.Error(w, errorx.NewApiError(http.StatusForbidden, "无法获取合适的授权信息"))
 			return
 		}
+		if len(apiKeyObj.OpenaiBase) == 0 {
+			httpx.Error(w, errorx.NewApiError(http.StatusForbidden, "缺失OpenaiBase"))
+			return
+		}
+
 		ctx = contextkey.AuthTokenInfoKey.WithValue(ctx, apiKeyObj)
-		ctx = contextkey.OpenapiTokenKey.WithValue(ctx, authToken)
 
 		newReq := r.WithContext(ctx)
 		// Passthrough to next handler if need

+ 1 - 1
internal/utils/compapi/config.go

@@ -13,7 +13,7 @@ const (
 
 type workIdInfo struct {
 	Id  string
-	Idx int
+	Idx uint
 }
 
 var fastgptWorkIdMap = map[string]workIdInfo{

+ 12 - 9
internal/utils/compapi/func.go

@@ -43,6 +43,7 @@ func DoChatCompletions(ctx context.Context, client *openai.Client, chatInfo *typ
 		return nil, err
 	}
 	//fmt.Printf("In DoChatCompletions, req: '%s'\n", string(jsonBytes))
+	//也许应该对请求体不规范成员名进行检查
 	customResp := types.CompOpenApiResp{}
 	reqBodyOps := option.WithRequestBody("application/json", jsonBytes)
 	respBodyOps := option.WithResponseBodyInto(&customResp)
@@ -190,20 +191,22 @@ func DoChatCompletionsStreamOld(ctx context.Context, client *openai.Client, chat
 	return nil, nil
 }
 
-// 获取workToken
-func GetWorkTokenByID(eventType string, workId string) string {
+func GetWorkInfoByID(eventType string, workId string) (string, uint) {
 	val, exist := fastgptWorkIdMap[workId]
 	if !exist {
 		val = fastgptWorkIdMap["default"]
 	}
-	return val.Id
+	return val.Id, val.Idx
+}
+
+// 获取workToken
+func GetWorkTokenByID(eventType string, workId string) string {
+	id, _ := GetWorkInfoByID(eventType, workId)
+	return id
 }
 
 // 获取workIdx
-func GetWorkIdxByID(eventType string, workId string) int {
-	val, exist := fastgptWorkIdMap[workId]
-	if !exist {
-		val = fastgptWorkIdMap["default"]
-	}
-	return val.Idx
+func GetWorkIdxByID(eventType string, workId string) uint {
+	_, idx := GetWorkInfoByID(eventType, workId)
+	return idx
 }

+ 321 - 0
internal/utils/typekit/print.go

@@ -0,0 +1,321 @@
+package typekit
+
+//package main
+
+import (
+	"fmt"
+	"reflect"
+	"sort"
+	"strconv"
+	"strings"
+	"unsafe"
+)
+
+const (
+	colorReset  = "\033[0m"
+	colorStruct = "\033[34m\033[7m"
+	colorField  = "\033[32m"
+	colorMap    = "\033[33m\033[7m"
+	colorSlice  = "\033[35m\033[7m"
+	colorValue  = "\033[31m"
+	colorKey    = "\033[36m"
+	symbolVert  = "│  "
+	symbolLast  = "└─ "
+	symbolMid   = "├─ "
+	symbolEmpty = "   "
+)
+
+type PrintOptions struct {
+	ShowTypes bool
+}
+
+func PrettyPrint(v interface{}, opts ...PrintOptions) string {
+	option := PrintOptions{ShowTypes: true}
+	if len(opts) > 0 {
+		option = opts[0]
+	}
+	return prettyPrint(reflect.ValueOf(v), 0, make(map[uintptr]bool), option, []bool{}).String()
+}
+
+type lines []string
+
+func (l lines) String() string {
+	return strings.Join(l, "\n")
+}
+
+func buildPrefix(indent int, isLasts []bool) string {
+	var prefix strings.Builder
+	for i := 0; i < indent; i++ {
+		if i < len(isLasts) {
+			if isLasts[i] {
+				prefix.WriteString(symbolEmpty)
+			} else {
+				prefix.WriteString(symbolVert)
+			}
+		}
+	}
+	return prefix.String()
+}
+
+func prettyPrint(v reflect.Value, indentLevel int, visited map[uintptr]bool, opts PrintOptions, isLasts []bool) lines {
+	original := v
+	for {
+		switch v.Kind() {
+		case reflect.Ptr:
+			if v.IsNil() {
+				return lines{colorValue + "nil" + colorReset}
+			}
+			ptr := v.Pointer()
+			if visited[ptr] {
+				return lines{fmt.Sprintf("%s&%p%s", colorValue, v.Interface(), colorReset)}
+			}
+			visited[ptr] = true
+			original = v
+			v = v.Elem()
+		case reflect.Interface:
+			if v.IsNil() {
+				return lines{colorValue + "nil" + colorReset}
+			}
+			v = v.Elem()
+		default:
+			goto END_DEREF
+		}
+	}
+END_DEREF:
+
+	switch v.Kind() {
+	case reflect.Struct:
+		return printStruct(v, indentLevel, visited, opts, isLasts)
+	case reflect.Map:
+		return printMap(v, indentLevel, visited, opts, isLasts)
+	case reflect.Slice, reflect.Array:
+		return printSlice(v, indentLevel, visited, opts, isLasts)
+	case reflect.String:
+		return lines{fmt.Sprintf("%s%q%s", colorValue, v.String(), colorReset)}
+	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
+		return lines{fmt.Sprintf("%s%d%s", colorValue, v.Int(), colorReset)}
+	case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
+		return lines{fmt.Sprintf("%s%d%s", colorValue, v.Uint(), colorReset)}
+	case reflect.Float32, reflect.Float64:
+		// 使用精确的字符串表示,保留必要精度
+		str := strconv.FormatFloat(v.Float(), 'f', -1, 64)
+		// 移除多余的末尾零和小数点
+		if strings.Contains(str, ".") {
+			str = strings.TrimRight(str, "0")
+			str = strings.TrimRight(str, ".")
+		}
+		return lines{fmt.Sprintf("%s%s%s", colorValue, str, colorReset)}
+	case reflect.Bool:
+		return lines{fmt.Sprintf("%s%t%s", colorValue, v.Bool(), colorReset)}
+	default:
+		if original.Kind() == reflect.Ptr {
+			return lines{fmt.Sprintf("%s%v%s", colorValue, original.Interface(), colorReset)}
+		}
+		//return lines{fmt.Sprintf("%s%v%s", colorValue, v.Interface(), colorReset)}
+		return lines{formatUnexported(v, original)}
+	}
+}
+
+// 新增辅助函数处理未导出字段
+func formatUnexported(v, original reflect.Value) string {
+	var value interface{}
+	var canShow bool
+
+	// 尝试通过不同方式安全获取值
+	switch {
+	case v.CanInterface():
+		value = v.Interface()
+		canShow = true
+	case original.Kind() == reflect.Ptr && original.CanInterface():
+		value = original.Interface()
+		canShow = true
+	default:
+		canShow = false
+	}
+
+	// 特殊处理指针类型
+	if v.Kind() == reflect.Ptr && !v.IsNil() {
+		return fmt.Sprintf("%s&%p%s", colorValue, unsafe.Pointer(v.Pointer()), colorReset)
+	}
+
+	// 构造显示字符串
+	if canShow {
+		return fmt.Sprintf("%s%v%s", colorValue, value, colorReset)
+	}
+	return fmt.Sprintf("%s<unexported>%s", colorValue, colorReset)
+}
+
+func printStruct(v reflect.Value, indentLevel int, visited map[uintptr]bool, opts PrintOptions, parentLasts []bool) lines {
+	var header string
+	if opts.ShowTypes {
+		header = fmt.Sprintf("%s%s%s", colorStruct, v.Type().String(), colorReset)
+	} else {
+		header = " ---"
+	}
+
+	result := lines{header}
+	fieldCount := v.NumField()
+
+	for i := 0; i < fieldCount; i++ {
+		field := v.Type().Field(i)
+		// 跳过未导出字段
+		if !field.IsExported() {
+			continue
+		}
+		fieldValue := v.Field(i)
+		isLast := i == fieldCount-1
+
+		prefix := buildPrefix(indentLevel, parentLasts)
+		currentLasts := append(parentLasts, isLast)
+
+		var symbol string
+		if isLast {
+			symbol = symbolLast
+		} else {
+			symbol = symbolMid
+		}
+
+		fieldLines := prettyPrint(fieldValue, indentLevel+1, visited, opts, currentLasts)
+		fieldHeader := fmt.Sprintf("%s%s%s%s: ",
+			prefix,
+			symbol,
+			colorField,
+			field.Name,
+		)
+
+		if len(fieldLines) == 0 {
+			result = append(result, fieldHeader+colorValue+"<invalid>"+colorReset)
+			continue
+		}
+
+		result = append(result, fieldHeader+fieldLines[0])
+		for _, line := range fieldLines[1:] {
+			result = append(result, prefix+symbolEmpty+line)
+		}
+	}
+	return result
+}
+
+func printMap(v reflect.Value, indentLevel int, visited map[uintptr]bool, opts PrintOptions, parentLasts []bool) lines {
+	var header string
+	if opts.ShowTypes {
+		header = fmt.Sprintf("%s%s%s", colorMap, v.Type().String(), colorReset)
+	} else {
+		header = " ---"
+	}
+
+	result := lines{header}
+	keys := v.MapKeys()
+	sort.Slice(keys, func(i, j int) bool {
+		return fmt.Sprintf("%v", keys[i]) < fmt.Sprintf("%v", keys[j])
+	})
+	keyCount := len(keys)
+
+	for i, key := range keys {
+		prefix := buildPrefix(indentLevel, parentLasts)
+		isLast := i == keyCount-1
+		currentLasts := append(parentLasts, isLast)
+
+		var symbol string
+		if isLast {
+			symbol = symbolLast
+		} else {
+			symbol = symbolMid
+		}
+
+		keyLines := prettyPrint(key, 0, visited, opts, currentLasts)
+		valueLines := prettyPrint(v.MapIndex(key), indentLevel+1, visited, opts, currentLasts)
+
+		keyHeader := fmt.Sprintf("%s%s%s%s: ",
+			prefix,
+			symbol,
+			colorKey,
+			strings.Join(keyLines, ""),
+		)
+
+		if len(valueLines) == 0 {
+			result = append(result, keyHeader+colorValue+"<invalid>"+colorReset)
+			continue
+		}
+
+		result = append(result, keyHeader+valueLines[0])
+		for _, line := range valueLines[1:] {
+			result = append(result, prefix+symbolEmpty+line)
+		}
+	}
+	return result
+}
+
+func printSlice(v reflect.Value, indentLevel int, visited map[uintptr]bool, opts PrintOptions, parentLasts []bool) lines {
+	var header string
+	if opts.ShowTypes {
+		header = fmt.Sprintf("%s%s%s", colorSlice, v.Type().String(), colorReset)
+	} else {
+		header = " ---"
+	}
+
+	result := lines{header}
+	elemCount := v.Len()
+
+	for i := 0; i < elemCount; i++ {
+		prefix := buildPrefix(indentLevel, parentLasts)
+		isLast := i == elemCount-1
+		currentLasts := append(parentLasts, isLast)
+
+		var symbol string
+		if isLast {
+			symbol = symbolLast
+		} else {
+			symbol = symbolMid
+		}
+
+		elemLines := prettyPrint(v.Index(i), indentLevel+1, visited, opts, currentLasts)
+		bullet := fmt.Sprintf("%s%s", prefix, symbol)
+
+		if len(elemLines) == 0 {
+			result = append(result, bullet+colorValue+"<invalid>"+colorReset)
+			continue
+		}
+
+		result = append(result, bullet+elemLines[0])
+		for _, line := range elemLines[1:] {
+			result = append(result, prefix+symbolEmpty+line)
+		}
+	}
+	return result
+}
+
+/*
+type Person struct {
+	Name    string
+	Age     int
+	Hobbies []string
+	Address struct {
+		City  string
+		State string
+	}
+	Metadata map[string]interface{}
+}
+
+func main() {
+	p := Person{
+		Name:    "Alice",
+		Age:     30,
+		Hobbies: []string{"Reading", "Hiking"},
+		Metadata: map[string]interface{}{
+			"id":     123,
+			"scores": []float64{98.5, 87.2},
+			"nested": map[string]interface{}{"a": 1, "b": 2},
+		},
+	}
+	p.Address.City = "New York"
+	p.Address.State = "NY"
+	p.Metadata["self_ref"] = &p
+
+	fmt.Println("With types:")
+	fmt.Println(PrettyPrint(p, PrintOptions{ShowTypes: false}))
+
+	fmt.Println("\nWithout types:\n")
+	fmt.Println(PrettyPrint(p))
+}
+*/

+ 217 - 0
internal/utils/typekit/print.go.1

@@ -0,0 +1,217 @@
+package typekit
+
+import (
+	"fmt"
+	"reflect"
+	"sort"
+	"strings"
+)
+
+const (
+	colorReset  = "\033[0m"
+	colorStruct = "\033[34m"
+	colorField  = "\033[32m"
+	colorMap    = "\033[33m"
+	colorSlice  = "\033[35m"
+	colorValue  = "\033[31m"
+	colorKey    = "\033[36m"
+)
+
+func PrettyPrint(v interface{}) string {
+	return prettyPrint(reflect.ValueOf(v), 0, make(map[uintptr]bool)).String()
+}
+
+type lines []string
+
+func (l lines) String() string {
+	return strings.Join(l, "\n")
+}
+
+func prettyPrint(v reflect.Value, indentLevel int, visited map[uintptr]bool) lines {
+	original := v
+	// 改进的指针/接口处理逻辑
+	for {
+		switch v.Kind() {
+		case reflect.Ptr:
+			if v.IsNil() {
+				return lines{colorValue + "nil" + colorReset}
+			}
+			ptr := v.Pointer() // 使用正确获取指针值的方法
+			if visited[ptr] {
+				// 正确格式化指针地址
+				return lines{fmt.Sprintf("%s&%p%s", colorValue, v.Interface(), colorReset)}
+			}
+			visited[ptr] = true
+			original = v
+			v = v.Elem()
+		case reflect.Interface:
+			if v.IsNil() {
+				return lines{colorValue + "nil" + colorReset}
+			}
+			v = v.Elem()
+		default:
+			goto END_DEREF
+		}
+	}
+END_DEREF:
+
+	switch v.Kind() {
+	case reflect.Struct:
+		return printStruct(v, indentLevel, visited)
+	case reflect.Map:
+		return printMap(v, indentLevel, visited)
+	case reflect.Slice, reflect.Array:
+		return printSlice(v, indentLevel, visited)
+	case reflect.String:
+		return lines{fmt.Sprintf("%s%q%s", colorValue, v.String(), colorReset)}
+	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
+		return lines{fmt.Sprintf("%s%d%s", colorValue, v.Int(), colorReset)}
+	case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
+		return lines{fmt.Sprintf("%s%d%s", colorValue, v.Uint(), colorReset)}
+	case reflect.Float32, reflect.Float64:
+		return lines{fmt.Sprintf("%s%.2f%s", colorValue, v.Float(), colorReset)}
+	case reflect.Bool:
+		return lines{fmt.Sprintf("%s%t%s", colorValue, v.Bool(), colorReset)}
+	default:
+		if original.Kind() == reflect.Ptr {
+			return lines{fmt.Sprintf("%s%v%s", colorValue, original.Interface(), colorReset)}
+		}
+		return lines{fmt.Sprintf("%s%v%s", colorValue, v.Interface(), colorReset)}
+	}
+}
+
+// 完整实现结构体打印
+func printStruct(v reflect.Value, indentLevel int, visited map[uintptr]bool) lines {
+	header := fmt.Sprintf("%s%s%s%s:",
+		strings.Repeat("  ", indentLevel),
+		colorStruct,
+		v.Type().String(),
+		colorReset,
+	)
+	result := lines{header}
+
+	for i := 0; i < v.NumField(); i++ {
+		field := v.Type().Field(i)
+		fieldValue := v.Field(i)
+
+		fieldLines := prettyPrint(fieldValue, indentLevel+1, visited)
+		fieldHeader := fmt.Sprintf("%s%s%s: ",
+			strings.Repeat("  ", indentLevel+1),
+			colorField,
+			field.Name,
+		)
+
+		if len(fieldLines) == 0 {
+			result = append(result, fieldHeader+colorValue+"<invalid>"+colorReset)
+			continue
+		}
+
+		result = append(result, fieldHeader+fieldLines[0])
+		for _, line := range fieldLines[1:] {
+			result = append(result,
+				strings.Repeat("  ", indentLevel+1)+"  "+line)
+		}
+	}
+	return result
+}
+
+// 完整实现map打印
+func printMap(v reflect.Value, indentLevel int, visited map[uintptr]bool) lines {
+	header := fmt.Sprintf("%s%s%s%s:",
+		strings.Repeat("  ", indentLevel),
+		colorMap,
+		v.Type().String(),
+		colorReset,
+	)
+	result := lines{header}
+
+	keys := v.MapKeys()
+	sort.Slice(keys, func(i, j int) bool {
+		return fmt.Sprintf("%v", keys[i]) < fmt.Sprintf("%v", keys[j])
+	})
+
+	for _, key := range keys {
+		keyLines := prettyPrint(key, 0, visited)
+		valueLines := prettyPrint(v.MapIndex(key), indentLevel+1, visited)
+
+		keyHeader := fmt.Sprintf("%s%s%s: ",
+			strings.Repeat("  ", indentLevel+1),
+			colorKey,
+			strings.Join(keyLines, ""),
+		)
+
+		if len(valueLines) == 0 {
+			result = append(result, keyHeader+colorValue+"<invalid>"+colorReset)
+			continue
+		}
+
+		result = append(result, keyHeader+valueLines[0])
+		for _, line := range valueLines[1:] {
+			result = append(result,
+				strings.Repeat("  ", indentLevel+1)+"  "+line)
+		}
+	}
+	return result
+}
+
+// 完整实现slice/array打印
+func printSlice(v reflect.Value, indentLevel int, visited map[uintptr]bool) lines {
+	header := fmt.Sprintf("%s%s%s%s:",
+		strings.Repeat("  ", indentLevel),
+		colorSlice,
+		v.Type().String(),
+		colorReset,
+	)
+	result := lines{header}
+
+	for i := 0; i < v.Len(); i++ {
+		elemLines := prettyPrint(v.Index(i), indentLevel+1, visited)
+		bullet := fmt.Sprintf("%s- ",
+			strings.Repeat("  ", indentLevel+1),
+		)
+
+		if len(elemLines) == 0 {
+			result = append(result, bullet+colorValue+"<invalid>"+colorReset)
+			continue
+		}
+
+		result = append(result, bullet+elemLines[0])
+		for _, line := range elemLines[1:] {
+			result = append(result,
+				strings.Repeat("  ", indentLevel+1)+"  "+line)
+		}
+	}
+	return result
+}
+
+/*
+// 修正后的测试用例
+type Person struct {
+	Name    string
+	Age     int
+	Hobbies []string
+	Address struct {
+		City  string
+		State string
+	}
+	Metadata map[string]interface{}
+}
+
+func main() {
+	p := Person{
+		Name:    "Alice",
+		Age:     30,
+		Hobbies: []string{"Reading", "Hiking"},
+		Metadata: map[string]interface{}{
+			"id":     123,
+			"scores": []float64{98.5, 87.2},
+			"nested": map[string]interface{}{"a": 1, "b": 2},
+		},
+	}
+	p.Address.City = "New York"
+	p.Address.State = "NY"
+	p.Metadata["self_ref"] = &p // 正确设置循环引用
+
+	fmt.Println(PrettyPrint(p))
+}
+*/

+ 345 - 0
internal/utils/typekit/print.go.3

@@ -0,0 +1,345 @@
+package main
+
+import (
+	"fmt"
+	"os"
+	"reflect"
+	"sort"
+	"strconv"
+	"strings"
+
+	"github.com/muesli/termenv"
+)
+
+// 颜色配置枚举
+type ColorProfile int
+
+const (
+	Auto ColorProfile = iota
+	Dark
+	Light
+	NoColor
+)
+
+// 打印选项结构
+type PrintOptions struct {
+	ShowTypes      bool         // 是否显示类型信息
+	ColorProfile   ColorProfile // 颜色配置方案
+	FloatPrecision int          // 浮点数精度(-1表示自动)
+}
+
+// 颜色缓存变量
+var (
+	colorType  string
+	colorField string
+	colorKey   string
+	colorValue string
+	resetColor string
+)
+
+// 初始化颜色配置
+func initColors(profile ColorProfile) {
+	output := termenv.NewOutput(os.Stdout)
+	style := output.String()
+	resetColor = style.Reset().String()
+
+	switch profile {
+	case Auto:
+		if output.HasDarkBackground() {
+			setDarkThemeColors(output)
+		} else {
+			setLightThemeColors(output)
+		}
+	case Dark:
+		setDarkThemeColors(output)
+	case Light:
+		setLightThemeColors(output)
+	case NoColor:
+		colorType = ""
+		colorField = ""
+		colorKey = ""
+		colorValue = ""
+		resetColor = ""
+	}
+}
+
+// 暗色主题配色
+func setDarkThemeColors(output *termenv.Output) {
+	colorType = output.String().Foreground(output.Color("#5FAFFF")).String()
+	colorField = output.String().Foreground(output.Color("#AFF080")).String()
+	colorKey = output.String().Foreground(output.Color("#FFD700")).String()
+	colorValue = output.String().Foreground(output.Color("#E0E0E0")).String()
+}
+
+// 亮色主题配色
+func setLightThemeColors(output *termenv.Output) {
+	colorType = output.String().Foreground(output.Color("#005FAF")).String()
+	colorField = output.String().Foreground(output.Color("#008000")).String()
+	colorKey = output.String().Foreground(output.Color("#AF5F00")).String()
+	colorValue = output.String().Foreground(output.Color("#404040")).String()
+}
+
+// 美观打印入口函数
+func PrettyPrint(v interface{}, opts ...PrintOptions) string {
+	// 设置默认选项
+	option := PrintOptions{
+		ShowTypes:      true,
+		ColorProfile:   Auto,
+		FloatPrecision: -1,
+	}
+	if len(opts) > 0 {
+		option = opts[0]
+	}
+
+	// 初始化颜色
+	initColors(option.ColorProfile)
+
+	// 开始递归打印
+	return prettyPrint(reflect.ValueOf(v), 0, make(map[uintptr]bool), option, []bool{}).String()
+}
+
+// 行集合类型
+type lines []string
+
+func (l lines) String() string {
+	return strings.Join(l, "\n")
+}
+
+// 核心打印逻辑
+func prettyPrint(v reflect.Value, depth int, visited map[uintptr]bool, opts PrintOptions, lastMarkers []bool) lines {
+	original := v
+	// 处理指针和接口
+	for {
+		switch v.Kind() {
+		case reflect.Ptr:
+			if v.IsNil() {
+				return lines{colorValue + "nil" + resetColor}
+			}
+			ptr := v.Pointer()
+			if visited[ptr] {
+				return lines{fmt.Sprintf("%s&%p%s", colorValue, v.Interface(), resetColor)}
+			}
+			visited[ptr] = true
+			original = v
+			v = v.Elem()
+		case reflect.Interface:
+			if v.IsNil() {
+				return lines{colorValue + "nil" + resetColor}
+			}
+			v = v.Elem()
+		default:
+			goto END_DEREF
+		}
+	}
+END_DEREF:
+
+	var result lines
+	prefix := buildPrefix(depth, lastMarkers)
+
+	// 添加类型行
+	if opts.ShowTypes && depth == 0 {
+		typeLine := fmt.Sprintf("%s%s%s", colorType, getTypeName(original, v), resetColor)
+		result = append(result, typeLine)
+	}
+
+	switch v.Kind() {
+	case reflect.Struct:
+		result = append(result, printStruct(v, depth, visited, opts, lastMarkers)...)
+	case reflect.Map:
+		result = append(result, printMap(v, depth, visited, opts, lastMarkers)...)
+	case reflect.Slice, reflect.Array:
+		result = append(result, printSlice(v, depth, visited, opts, lastMarkers)...)
+	default:
+		result = append(result, formatValue(v, prefix, opts))
+	}
+
+	return result
+}
+
+// 构建前缀字符串
+func buildPrefix(depth int, lastMarkers []bool) string {
+	if depth == 0 {
+		return ""
+	}
+
+	var prefix strings.Builder
+	for i := 0; i < depth-1; i++ {
+		if i < len(lastMarkers) && lastMarkers[i] {
+			prefix.WriteString("    ")
+		} else {
+			prefix.WriteString("│   ")
+		}
+	}
+
+	if depth > 0 {
+		if len(lastMarkers) > 0 && lastMarkers[len(lastMarkers)-1] {
+			prefix.WriteString("└── ")
+		} else {
+			prefix.WriteString("├── ")
+		}
+	}
+	return prefix.String()
+}
+
+// 获取类型名称
+func getTypeName(original, v reflect.Value) string {
+	if original.Kind() == reflect.Ptr {
+		return original.Type().String()
+	}
+	return v.Type().String()
+}
+
+// 格式化值
+func formatValue(v reflect.Value, prefix string, opts PrintOptions) string {
+	switch v.Kind() {
+	case reflect.String:
+		return fmt.Sprintf("%s%s%q%s", prefix, colorValue, v.String(), resetColor)
+	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
+		return fmt.Sprintf("%s%s%d%s", prefix, colorValue, v.Int(), resetColor)
+	case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
+		return fmt.Sprintf("%s%s%d%s", prefix, colorValue, v.Uint(), resetColor)
+	case reflect.Float32, reflect.Float64:
+		return formatFloat(v.Float(), opts.FloatPrecision, prefix)
+	case reflect.Bool:
+		return fmt.Sprintf("%s%s%t%s", prefix, colorValue, v.Bool(), resetColor)
+	default:
+		return fmt.Sprintf("%s%s%v%s", prefix, colorValue, v.Interface(), resetColor)
+	}
+}
+
+// 格式化浮点数(改进精度处理)
+func formatFloat(f float64, precision int, prefix string) string {
+	var str string
+	if precision >= 0 {
+		str = strconv.FormatFloat(f, 'f', precision, 64)
+	} else {
+		// 自动处理精度
+		str = strconv.FormatFloat(f, 'f', -1, 64)
+		if strings.Contains(str, ".") {
+			str = strings.TrimRight(str, "0")
+			str = strings.TrimRight(str, ".")
+		}
+	}
+	return fmt.Sprintf("%s%s%s%s", prefix, colorValue, str, resetColor)
+}
+
+// 打印结构体
+func printStruct(v reflect.Value, depth int, visited map[uintptr]bool, opts PrintOptions, lastMarkers []bool) lines {
+	var result lines
+	fieldCount := v.NumField()
+
+	for i := 0; i < fieldCount; i++ {
+		field := v.Type().Field(i)
+		fieldValue := v.Field(i)
+		isLast := i == fieldCount-1
+
+		newMarkers := append(lastMarkers, isLast)
+		subLines := prettyPrint(fieldValue, depth+1, visited, opts, newMarkers)
+
+		// 字段头
+		fieldHeader := fmt.Sprintf("%s%s%s:",
+			buildPrefix(depth+1, newMarkers[:len(newMarkers)-1]),
+			colorField,
+			field.Name,
+		)
+
+		if len(subLines) == 0 {
+			result = append(result, fieldHeader+colorValue+"<invalid>"+resetColor)
+			continue
+		}
+
+		// 合并字段头和数据
+		result = append(result, fieldHeader+strings.TrimPrefix(subLines[0], buildPrefix(depth+1, newMarkers)))
+		result = append(result, subLines[1:]...)
+	}
+	return result
+}
+
+// 打印Map
+func printMap(v reflect.Value, depth int, visited map[uintptr]bool, opts PrintOptions, lastMarkers []bool) lines {
+	var result lines
+	keys := v.MapKeys()
+	sort.Slice(keys, func(i, j int) bool {
+		return fmt.Sprintf("%v", keys[i]) < fmt.Sprintf("%v", keys[j])
+	})
+
+	for i, key := range keys {
+		isLast := i == len(keys)-1
+		newMarkers := append(lastMarkers, isLast)
+
+		keyLines := prettyPrint(key, depth+1, visited, opts, newMarkers)
+		valueLines := prettyPrint(v.MapIndex(key), depth+1, visited, opts, newMarkers)
+
+		// Key头
+		keyHeader := fmt.Sprintf("%s%s%s:",
+			buildPrefix(depth+1, newMarkers[:len(newMarkers)-1]),
+			colorKey,
+			strings.Join(keyLines, ""),
+		)
+
+		// 合并Key和Value
+		if len(valueLines) > 0 {
+			result = append(result, keyHeader+strings.TrimPrefix(valueLines[0], buildPrefix(depth+1, newMarkers)))
+			result = append(result, valueLines[1:]...)
+		} else {
+			result = append(result, keyHeader+"<invalid>")
+		}
+	}
+	return result
+}
+
+// 打印Slice/Array
+func printSlice(v reflect.Value, depth int, visited map[uintptr]bool, opts PrintOptions, lastMarkers []bool) lines {
+	var result lines
+	for i := 0; i < v.Len(); i++ {
+		isLast := i == v.Len()-1
+		newMarkers := append(lastMarkers, isLast)
+		elemLines := prettyPrint(v.Index(i), depth+1, visited, opts, newMarkers)
+		result = append(result, elemLines...)
+	}
+	return result
+}
+
+// 测试结构体
+type Person struct {
+	Name    string
+	Age     int
+	Hobbies []string
+	Address struct {
+		City  string
+		State string
+	}
+	Metadata map[string]interface{}
+}
+
+func main() {
+	p := Person{
+		Name:    "Alice",
+		Age:     30,
+		Hobbies: []string{"Reading", "Hiking"},
+		Metadata: map[string]interface{}{
+			"id":     123,
+			"scores": []float64{98.5, 87.2000, 100.0},
+			"nested": map[string]interface{}{"a": 1, "b": 2},
+		},
+	}
+	p.Address.City = "New York"
+	p.Address.State = "NY"
+	p.Metadata["self_ref"] = &p
+
+	fmt.Println("=== 默认输出(自动颜色适配)===")
+	fmt.Println(PrettyPrint(p))
+
+	fmt.Println("\n=== 显示类型+亮色主题+浮点精度2位 ===")
+	fmt.Println(PrettyPrint(p, PrintOptions{
+		ShowTypes:      true,
+		ColorProfile:   Light,
+		FloatPrecision: 2,
+	}))
+
+	fmt.Println("\n=== 不显示类型+暗色主题 ===")
+	fmt.Println(PrettyPrint(p, PrintOptions{
+		ShowTypes:    false,
+		ColorProfile: Dark,
+	}))
+}