Răsfoiți Sursa

增加微信发送定时任务

boweniac 10 luni în urmă
părinte
comite
ef5475ef3b

+ 154 - 11
ent/client.go

@@ -15,6 +15,7 @@ import (
 	"entgo.io/ent/dialect"
 	"entgo.io/ent/dialect/sql"
 	"entgo.io/ent/dialect/sql/sqlgraph"
+	"github.com/suyuan32/simple-admin-job/ent/messagerecords"
 	"github.com/suyuan32/simple-admin-job/ent/task"
 	"github.com/suyuan32/simple-admin-job/ent/tasklog"
 
@@ -26,6 +27,8 @@ type Client struct {
 	config
 	// Schema is the client for creating, migrating and dropping schema.
 	Schema *migrate.Schema
+	// MessageRecords is the client for interacting with the MessageRecords builders.
+	MessageRecords *MessageRecordsClient
 	// Task is the client for interacting with the Task builders.
 	Task *TaskClient
 	// TaskLog is the client for interacting with the TaskLog builders.
@@ -41,6 +44,7 @@ func NewClient(opts ...Option) *Client {
 
 func (c *Client) init() {
 	c.Schema = migrate.NewSchema(c.driver)
+	c.MessageRecords = NewMessageRecordsClient(c.config)
 	c.Task = NewTaskClient(c.config)
 	c.TaskLog = NewTaskLogClient(c.config)
 }
@@ -133,10 +137,11 @@ func (c *Client) Tx(ctx context.Context) (*Tx, error) {
 	cfg := c.config
 	cfg.driver = tx
 	return &Tx{
-		ctx:     ctx,
-		config:  cfg,
-		Task:    NewTaskClient(cfg),
-		TaskLog: NewTaskLogClient(cfg),
+		ctx:            ctx,
+		config:         cfg,
+		MessageRecords: NewMessageRecordsClient(cfg),
+		Task:           NewTaskClient(cfg),
+		TaskLog:        NewTaskLogClient(cfg),
 	}, nil
 }
 
@@ -154,17 +159,18 @@ func (c *Client) BeginTx(ctx context.Context, opts *sql.TxOptions) (*Tx, error)
 	cfg := c.config
 	cfg.driver = &txDriver{tx: tx, drv: c.driver}
 	return &Tx{
-		ctx:     ctx,
-		config:  cfg,
-		Task:    NewTaskClient(cfg),
-		TaskLog: NewTaskLogClient(cfg),
+		ctx:            ctx,
+		config:         cfg,
+		MessageRecords: NewMessageRecordsClient(cfg),
+		Task:           NewTaskClient(cfg),
+		TaskLog:        NewTaskLogClient(cfg),
 	}, nil
 }
 
 // Debug returns a new debug-client. It's used to get verbose logging on specific operations.
 //
 //	client.Debug().
-//		Task.
+//		MessageRecords.
 //		Query().
 //		Count(ctx)
 func (c *Client) Debug() *Client {
@@ -186,6 +192,7 @@ func (c *Client) Close() error {
 // Use adds the mutation hooks to all the entity clients.
 // In order to add hooks to a specific client, call: `client.Node.Use(...)`.
 func (c *Client) Use(hooks ...Hook) {
+	c.MessageRecords.Use(hooks...)
 	c.Task.Use(hooks...)
 	c.TaskLog.Use(hooks...)
 }
@@ -193,6 +200,7 @@ func (c *Client) Use(hooks ...Hook) {
 // Intercept adds the query interceptors to all the entity clients.
 // In order to add interceptors to a specific client, call: `client.Node.Intercept(...)`.
 func (c *Client) Intercept(interceptors ...Interceptor) {
+	c.MessageRecords.Intercept(interceptors...)
 	c.Task.Intercept(interceptors...)
 	c.TaskLog.Intercept(interceptors...)
 }
@@ -200,6 +208,8 @@ func (c *Client) Intercept(interceptors ...Interceptor) {
 // Mutate implements the ent.Mutator interface.
 func (c *Client) Mutate(ctx context.Context, m Mutation) (Value, error) {
 	switch m := m.(type) {
+	case *MessageRecordsMutation:
+		return c.MessageRecords.mutate(ctx, m)
 	case *TaskMutation:
 		return c.Task.mutate(ctx, m)
 	case *TaskLogMutation:
@@ -209,6 +219,139 @@ func (c *Client) Mutate(ctx context.Context, m Mutation) (Value, error) {
 	}
 }
 
+// MessageRecordsClient is a client for the MessageRecords schema.
+type MessageRecordsClient struct {
+	config
+}
+
+// NewMessageRecordsClient returns a client for the MessageRecords from the given config.
+func NewMessageRecordsClient(c config) *MessageRecordsClient {
+	return &MessageRecordsClient{config: c}
+}
+
+// Use adds a list of mutation hooks to the hooks stack.
+// A call to `Use(f, g, h)` equals to `messagerecords.Hooks(f(g(h())))`.
+func (c *MessageRecordsClient) Use(hooks ...Hook) {
+	c.hooks.MessageRecords = append(c.hooks.MessageRecords, hooks...)
+}
+
+// Intercept adds a list of query interceptors to the interceptors stack.
+// A call to `Intercept(f, g, h)` equals to `messagerecords.Intercept(f(g(h())))`.
+func (c *MessageRecordsClient) Intercept(interceptors ...Interceptor) {
+	c.inters.MessageRecords = append(c.inters.MessageRecords, interceptors...)
+}
+
+// Create returns a builder for creating a MessageRecords entity.
+func (c *MessageRecordsClient) Create() *MessageRecordsCreate {
+	mutation := newMessageRecordsMutation(c.config, OpCreate)
+	return &MessageRecordsCreate{config: c.config, hooks: c.Hooks(), mutation: mutation}
+}
+
+// CreateBulk returns a builder for creating a bulk of MessageRecords entities.
+func (c *MessageRecordsClient) CreateBulk(builders ...*MessageRecordsCreate) *MessageRecordsCreateBulk {
+	return &MessageRecordsCreateBulk{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 *MessageRecordsClient) MapCreateBulk(slice any, setFunc func(*MessageRecordsCreate, int)) *MessageRecordsCreateBulk {
+	rv := reflect.ValueOf(slice)
+	if rv.Kind() != reflect.Slice {
+		return &MessageRecordsCreateBulk{err: fmt.Errorf("calling to MessageRecordsClient.MapCreateBulk with wrong type %T, need slice", slice)}
+	}
+	builders := make([]*MessageRecordsCreate, rv.Len())
+	for i := 0; i < rv.Len(); i++ {
+		builders[i] = c.Create()
+		setFunc(builders[i], i)
+	}
+	return &MessageRecordsCreateBulk{config: c.config, builders: builders}
+}
+
+// Update returns an update builder for MessageRecords.
+func (c *MessageRecordsClient) Update() *MessageRecordsUpdate {
+	mutation := newMessageRecordsMutation(c.config, OpUpdate)
+	return &MessageRecordsUpdate{config: c.config, hooks: c.Hooks(), mutation: mutation}
+}
+
+// UpdateOne returns an update builder for the given entity.
+func (c *MessageRecordsClient) UpdateOne(mr *MessageRecords) *MessageRecordsUpdateOne {
+	mutation := newMessageRecordsMutation(c.config, OpUpdateOne, withMessageRecords(mr))
+	return &MessageRecordsUpdateOne{config: c.config, hooks: c.Hooks(), mutation: mutation}
+}
+
+// UpdateOneID returns an update builder for the given id.
+func (c *MessageRecordsClient) UpdateOneID(id uint64) *MessageRecordsUpdateOne {
+	mutation := newMessageRecordsMutation(c.config, OpUpdateOne, withMessageRecordsID(id))
+	return &MessageRecordsUpdateOne{config: c.config, hooks: c.Hooks(), mutation: mutation}
+}
+
+// Delete returns a delete builder for MessageRecords.
+func (c *MessageRecordsClient) Delete() *MessageRecordsDelete {
+	mutation := newMessageRecordsMutation(c.config, OpDelete)
+	return &MessageRecordsDelete{config: c.config, hooks: c.Hooks(), mutation: mutation}
+}
+
+// DeleteOne returns a builder for deleting the given entity.
+func (c *MessageRecordsClient) DeleteOne(mr *MessageRecords) *MessageRecordsDeleteOne {
+	return c.DeleteOneID(mr.ID)
+}
+
+// DeleteOneID returns a builder for deleting the given entity by its id.
+func (c *MessageRecordsClient) DeleteOneID(id uint64) *MessageRecordsDeleteOne {
+	builder := c.Delete().Where(messagerecords.ID(id))
+	builder.mutation.id = &id
+	builder.mutation.op = OpDeleteOne
+	return &MessageRecordsDeleteOne{builder}
+}
+
+// Query returns a query builder for MessageRecords.
+func (c *MessageRecordsClient) Query() *MessageRecordsQuery {
+	return &MessageRecordsQuery{
+		config: c.config,
+		ctx:    &QueryContext{Type: TypeMessageRecords},
+		inters: c.Interceptors(),
+	}
+}
+
+// Get returns a MessageRecords entity by its id.
+func (c *MessageRecordsClient) Get(ctx context.Context, id uint64) (*MessageRecords, error) {
+	return c.Query().Where(messagerecords.ID(id)).Only(ctx)
+}
+
+// GetX is like Get, but panics if an error occurs.
+func (c *MessageRecordsClient) GetX(ctx context.Context, id uint64) *MessageRecords {
+	obj, err := c.Get(ctx, id)
+	if err != nil {
+		panic(err)
+	}
+	return obj
+}
+
+// Hooks returns the client hooks.
+func (c *MessageRecordsClient) Hooks() []Hook {
+	return c.hooks.MessageRecords
+}
+
+// Interceptors returns the client interceptors.
+func (c *MessageRecordsClient) Interceptors() []Interceptor {
+	return c.inters.MessageRecords
+}
+
+func (c *MessageRecordsClient) mutate(ctx context.Context, m *MessageRecordsMutation) (Value, error) {
+	switch m.Op() {
+	case OpCreate:
+		return (&MessageRecordsCreate{config: c.config, hooks: c.Hooks(), mutation: m}).Save(ctx)
+	case OpUpdate:
+		return (&MessageRecordsUpdate{config: c.config, hooks: c.Hooks(), mutation: m}).Save(ctx)
+	case OpUpdateOne:
+		return (&MessageRecordsUpdateOne{config: c.config, hooks: c.Hooks(), mutation: m}).Save(ctx)
+	case OpDelete, OpDeleteOne:
+		return (&MessageRecordsDelete{config: c.config, hooks: c.Hooks(), mutation: m}).Exec(ctx)
+	default:
+		return nil, fmt.Errorf("ent: unknown MessageRecords mutation op: %q", m.Op())
+	}
+}
+
 // TaskClient is a client for the Task schema.
 type TaskClient struct {
 	config
@@ -510,10 +653,10 @@ func (c *TaskLogClient) mutate(ctx context.Context, m *TaskLogMutation) (Value,
 // hooks and interceptors per client, for fast access.
 type (
 	hooks struct {
-		Task, TaskLog []ent.Hook
+		MessageRecords, Task, TaskLog []ent.Hook
 	}
 	inters struct {
-		Task, TaskLog []ent.Interceptor
+		MessageRecords, Task, TaskLog []ent.Interceptor
 	}
 )
 

+ 4 - 2
ent/ent.go

@@ -12,6 +12,7 @@ import (
 	"entgo.io/ent"
 	"entgo.io/ent/dialect/sql"
 	"entgo.io/ent/dialect/sql/sqlgraph"
+	"github.com/suyuan32/simple-admin-job/ent/messagerecords"
 	"github.com/suyuan32/simple-admin-job/ent/task"
 	"github.com/suyuan32/simple-admin-job/ent/tasklog"
 )
@@ -74,8 +75,9 @@ var (
 func checkColumn(table, column string) error {
 	initCheck.Do(func() {
 		columnCheck = sql.NewColumnCheck(map[string]func(string) bool{
-			task.Table:    task.ValidColumn,
-			tasklog.Table: tasklog.ValidColumn,
+			messagerecords.Table: messagerecords.ValidColumn,
+			task.Table:           task.ValidColumn,
+			tasklog.Table:        tasklog.ValidColumn,
 		})
 	})
 	return columnCheck(table, column)

+ 12 - 0
ent/hook/hook.go

@@ -9,6 +9,18 @@ import (
 	"github.com/suyuan32/simple-admin-job/ent"
 )
 
+// The MessageRecordsFunc type is an adapter to allow the use of ordinary
+// function as MessageRecords mutator.
+type MessageRecordsFunc func(context.Context, *ent.MessageRecordsMutation) (ent.Value, error)
+
+// Mutate calls f(ctx, m).
+func (f MessageRecordsFunc) Mutate(ctx context.Context, m ent.Mutation) (ent.Value, error) {
+	if mv, ok := m.(*ent.MessageRecordsMutation); ok {
+		return f(ctx, mv)
+	}
+	return nil, fmt.Errorf("unexpected mutation type %T. expect *ent.MessageRecordsMutation", m)
+}
+
 // The TaskFunc type is an adapter to allow the use of ordinary
 // function as Task mutator.
 type TaskFunc func(context.Context, *ent.TaskMutation) (ent.Value, error)

+ 249 - 0
ent/messagerecords.go

@@ -0,0 +1,249 @@
+// Code generated by ent, DO NOT EDIT.
+
+package ent
+
+import (
+	"fmt"
+	"strings"
+	"time"
+
+	"entgo.io/ent"
+	"entgo.io/ent/dialect/sql"
+	"github.com/suyuan32/simple-admin-job/ent/messagerecords"
+)
+
+// MessageRecords is the model entity for the MessageRecords schema.
+type MessageRecords struct {
+	config `json:"-"`
+	// ID of the ent.
+	ID uint64 `json:"id,omitempty"`
+	// Create Time | 创建日期
+	CreatedAt time.Time `json:"created_at,omitempty"`
+	// Update Time | 修改日期
+	UpdatedAt time.Time `json:"updated_at,omitempty"`
+	// Status 1: normal 2: ban | 状态 1 正常 2 禁用
+	Status uint8 `json:"status,omitempty"`
+	// 机器人微信 id
+	BotWxid string `json:"bot_wxid,omitempty"`
+	// 联系人 id
+	ContactID uint64 `json:"contact_id,omitempty"`
+	// 类型:1好友,2群组,3企业微信联系人
+	ContactType int `json:"contact_type,omitempty"`
+	// 接收方微信 id
+	ContactWxid string `json:"contact_wxid,omitempty"`
+	// 内容类型 1 文本 2 文件
+	ContentType int `json:"content_type,omitempty"`
+	// 发送内容
+	Content string `json:"content,omitempty"`
+	// 异常原因
+	ErrorDetail string `json:"error_detail,omitempty"`
+	// 发送时间
+	SendTime time.Time `json:"send_time,omitempty"`
+	// 源类型 1 点发 2 群发 3 SOP
+	SourceType int `json:"source_type,omitempty"`
+	// 源 ID
+	SourceID uint64 `json:"source_id,omitempty"`
+	// 次源 ID
+	SubSourceID  uint64 `json:"sub_source_id,omitempty"`
+	selectValues sql.SelectValues
+}
+
+// scanValues returns the types for scanning values from sql.Rows.
+func (*MessageRecords) scanValues(columns []string) ([]any, error) {
+	values := make([]any, len(columns))
+	for i := range columns {
+		switch columns[i] {
+		case messagerecords.FieldID, messagerecords.FieldStatus, messagerecords.FieldContactID, messagerecords.FieldContactType, messagerecords.FieldContentType, messagerecords.FieldSourceType, messagerecords.FieldSourceID, messagerecords.FieldSubSourceID:
+			values[i] = new(sql.NullInt64)
+		case messagerecords.FieldBotWxid, messagerecords.FieldContactWxid, messagerecords.FieldContent, messagerecords.FieldErrorDetail:
+			values[i] = new(sql.NullString)
+		case messagerecords.FieldCreatedAt, messagerecords.FieldUpdatedAt, messagerecords.FieldSendTime:
+			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 MessageRecords fields.
+func (mr *MessageRecords) 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 messagerecords.FieldID:
+			value, ok := values[i].(*sql.NullInt64)
+			if !ok {
+				return fmt.Errorf("unexpected type %T for field id", value)
+			}
+			mr.ID = uint64(value.Int64)
+		case messagerecords.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 {
+				mr.CreatedAt = value.Time
+			}
+		case messagerecords.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 {
+				mr.UpdatedAt = value.Time
+			}
+		case messagerecords.FieldStatus:
+			if value, ok := values[i].(*sql.NullInt64); !ok {
+				return fmt.Errorf("unexpected type %T for field status", values[i])
+			} else if value.Valid {
+				mr.Status = uint8(value.Int64)
+			}
+		case messagerecords.FieldBotWxid:
+			if value, ok := values[i].(*sql.NullString); !ok {
+				return fmt.Errorf("unexpected type %T for field bot_wxid", values[i])
+			} else if value.Valid {
+				mr.BotWxid = value.String
+			}
+		case messagerecords.FieldContactID:
+			if value, ok := values[i].(*sql.NullInt64); !ok {
+				return fmt.Errorf("unexpected type %T for field contact_id", values[i])
+			} else if value.Valid {
+				mr.ContactID = uint64(value.Int64)
+			}
+		case messagerecords.FieldContactType:
+			if value, ok := values[i].(*sql.NullInt64); !ok {
+				return fmt.Errorf("unexpected type %T for field contact_type", values[i])
+			} else if value.Valid {
+				mr.ContactType = int(value.Int64)
+			}
+		case messagerecords.FieldContactWxid:
+			if value, ok := values[i].(*sql.NullString); !ok {
+				return fmt.Errorf("unexpected type %T for field contact_wxid", values[i])
+			} else if value.Valid {
+				mr.ContactWxid = value.String
+			}
+		case messagerecords.FieldContentType:
+			if value, ok := values[i].(*sql.NullInt64); !ok {
+				return fmt.Errorf("unexpected type %T for field content_type", values[i])
+			} else if value.Valid {
+				mr.ContentType = int(value.Int64)
+			}
+		case messagerecords.FieldContent:
+			if value, ok := values[i].(*sql.NullString); !ok {
+				return fmt.Errorf("unexpected type %T for field content", values[i])
+			} else if value.Valid {
+				mr.Content = value.String
+			}
+		case messagerecords.FieldErrorDetail:
+			if value, ok := values[i].(*sql.NullString); !ok {
+				return fmt.Errorf("unexpected type %T for field error_detail", values[i])
+			} else if value.Valid {
+				mr.ErrorDetail = value.String
+			}
+		case messagerecords.FieldSendTime:
+			if value, ok := values[i].(*sql.NullTime); !ok {
+				return fmt.Errorf("unexpected type %T for field send_time", values[i])
+			} else if value.Valid {
+				mr.SendTime = value.Time
+			}
+		case messagerecords.FieldSourceType:
+			if value, ok := values[i].(*sql.NullInt64); !ok {
+				return fmt.Errorf("unexpected type %T for field source_type", values[i])
+			} else if value.Valid {
+				mr.SourceType = int(value.Int64)
+			}
+		case messagerecords.FieldSourceID:
+			if value, ok := values[i].(*sql.NullInt64); !ok {
+				return fmt.Errorf("unexpected type %T for field source_id", values[i])
+			} else if value.Valid {
+				mr.SourceID = uint64(value.Int64)
+			}
+		case messagerecords.FieldSubSourceID:
+			if value, ok := values[i].(*sql.NullInt64); !ok {
+				return fmt.Errorf("unexpected type %T for field sub_source_id", values[i])
+			} else if value.Valid {
+				mr.SubSourceID = uint64(value.Int64)
+			}
+		default:
+			mr.selectValues.Set(columns[i], values[i])
+		}
+	}
+	return nil
+}
+
+// Value returns the ent.Value that was dynamically selected and assigned to the MessageRecords.
+// This includes values selected through modifiers, order, etc.
+func (mr *MessageRecords) Value(name string) (ent.Value, error) {
+	return mr.selectValues.Get(name)
+}
+
+// Update returns a builder for updating this MessageRecords.
+// Note that you need to call MessageRecords.Unwrap() before calling this method if this MessageRecords
+// was returned from a transaction, and the transaction was committed or rolled back.
+func (mr *MessageRecords) Update() *MessageRecordsUpdateOne {
+	return NewMessageRecordsClient(mr.config).UpdateOne(mr)
+}
+
+// Unwrap unwraps the MessageRecords 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 (mr *MessageRecords) Unwrap() *MessageRecords {
+	_tx, ok := mr.config.driver.(*txDriver)
+	if !ok {
+		panic("ent: MessageRecords is not a transactional entity")
+	}
+	mr.config.driver = _tx.drv
+	return mr
+}
+
+// String implements the fmt.Stringer.
+func (mr *MessageRecords) String() string {
+	var builder strings.Builder
+	builder.WriteString("MessageRecords(")
+	builder.WriteString(fmt.Sprintf("id=%v, ", mr.ID))
+	builder.WriteString("created_at=")
+	builder.WriteString(mr.CreatedAt.Format(time.ANSIC))
+	builder.WriteString(", ")
+	builder.WriteString("updated_at=")
+	builder.WriteString(mr.UpdatedAt.Format(time.ANSIC))
+	builder.WriteString(", ")
+	builder.WriteString("status=")
+	builder.WriteString(fmt.Sprintf("%v", mr.Status))
+	builder.WriteString(", ")
+	builder.WriteString("bot_wxid=")
+	builder.WriteString(mr.BotWxid)
+	builder.WriteString(", ")
+	builder.WriteString("contact_id=")
+	builder.WriteString(fmt.Sprintf("%v", mr.ContactID))
+	builder.WriteString(", ")
+	builder.WriteString("contact_type=")
+	builder.WriteString(fmt.Sprintf("%v", mr.ContactType))
+	builder.WriteString(", ")
+	builder.WriteString("contact_wxid=")
+	builder.WriteString(mr.ContactWxid)
+	builder.WriteString(", ")
+	builder.WriteString("content_type=")
+	builder.WriteString(fmt.Sprintf("%v", mr.ContentType))
+	builder.WriteString(", ")
+	builder.WriteString("content=")
+	builder.WriteString(mr.Content)
+	builder.WriteString(", ")
+	builder.WriteString("error_detail=")
+	builder.WriteString(mr.ErrorDetail)
+	builder.WriteString(", ")
+	builder.WriteString("send_time=")
+	builder.WriteString(mr.SendTime.Format(time.ANSIC))
+	builder.WriteString(", ")
+	builder.WriteString("source_type=")
+	builder.WriteString(fmt.Sprintf("%v", mr.SourceType))
+	builder.WriteString(", ")
+	builder.WriteString("source_id=")
+	builder.WriteString(fmt.Sprintf("%v", mr.SourceID))
+	builder.WriteString(", ")
+	builder.WriteString("sub_source_id=")
+	builder.WriteString(fmt.Sprintf("%v", mr.SubSourceID))
+	builder.WriteByte(')')
+	return builder.String()
+}
+
+// MessageRecordsSlice is a parsable slice of MessageRecords.
+type MessageRecordsSlice []*MessageRecords

+ 180 - 0
ent/messagerecords/messagerecords.go

@@ -0,0 +1,180 @@
+// Code generated by ent, DO NOT EDIT.
+
+package messagerecords
+
+import (
+	"time"
+
+	"entgo.io/ent/dialect/sql"
+)
+
+const (
+	// Label holds the string label denoting the messagerecords type in the database.
+	Label = "message_records"
+	// FieldID holds the string denoting the id field in the database.
+	FieldID = "id"
+	// FieldCreatedAt holds the string denoting the created_at field in the database.
+	FieldCreatedAt = "created_at"
+	// FieldUpdatedAt holds the string denoting the updated_at field in the database.
+	FieldUpdatedAt = "updated_at"
+	// FieldStatus holds the string denoting the status field in the database.
+	FieldStatus = "status"
+	// FieldBotWxid holds the string denoting the bot_wxid field in the database.
+	FieldBotWxid = "bot_wxid"
+	// FieldContactID holds the string denoting the contact_id field in the database.
+	FieldContactID = "contact_id"
+	// FieldContactType holds the string denoting the contact_type field in the database.
+	FieldContactType = "contact_type"
+	// FieldContactWxid holds the string denoting the contact_wxid field in the database.
+	FieldContactWxid = "contact_wxid"
+	// FieldContentType holds the string denoting the content_type field in the database.
+	FieldContentType = "content_type"
+	// FieldContent holds the string denoting the content field in the database.
+	FieldContent = "content"
+	// FieldErrorDetail holds the string denoting the error_detail field in the database.
+	FieldErrorDetail = "error_detail"
+	// FieldSendTime holds the string denoting the send_time field in the database.
+	FieldSendTime = "send_time"
+	// FieldSourceType holds the string denoting the source_type field in the database.
+	FieldSourceType = "source_type"
+	// FieldSourceID holds the string denoting the source_id field in the database.
+	FieldSourceID = "source_id"
+	// FieldSubSourceID holds the string denoting the sub_source_id field in the database.
+	FieldSubSourceID = "sub_source_id"
+	// Table holds the table name of the messagerecords in the database.
+	Table = "message_records"
+)
+
+// Columns holds all SQL columns for messagerecords fields.
+var Columns = []string{
+	FieldID,
+	FieldCreatedAt,
+	FieldUpdatedAt,
+	FieldStatus,
+	FieldBotWxid,
+	FieldContactID,
+	FieldContactType,
+	FieldContactWxid,
+	FieldContentType,
+	FieldContent,
+	FieldErrorDetail,
+	FieldSendTime,
+	FieldSourceType,
+	FieldSourceID,
+	FieldSubSourceID,
+}
+
+// ValidColumn reports if the column name is valid (part of the table columns).
+func ValidColumn(column string) bool {
+	for i := range Columns {
+		if column == Columns[i] {
+			return true
+		}
+	}
+	return false
+}
+
+var (
+	// DefaultCreatedAt holds the default value on creation for the "created_at" field.
+	DefaultCreatedAt func() time.Time
+	// DefaultUpdatedAt holds the default value on creation for the "updated_at" field.
+	DefaultUpdatedAt func() time.Time
+	// UpdateDefaultUpdatedAt holds the default value on update for the "updated_at" field.
+	UpdateDefaultUpdatedAt func() time.Time
+	// DefaultStatus holds the default value on creation for the "status" field.
+	DefaultStatus uint8
+	// DefaultContactType holds the default value on creation for the "contact_type" field.
+	DefaultContactType int
+	// DefaultContactWxid holds the default value on creation for the "contact_wxid" field.
+	DefaultContactWxid string
+	// DefaultContentType holds the default value on creation for the "content_type" field.
+	DefaultContentType int
+	// DefaultContent holds the default value on creation for the "content" field.
+	DefaultContent string
+	// DefaultErrorDetail holds the default value on creation for the "error_detail" field.
+	DefaultErrorDetail string
+	// DefaultSourceType holds the default value on creation for the "source_type" field.
+	DefaultSourceType int
+	// DefaultSourceID holds the default value on creation for the "source_id" field.
+	DefaultSourceID uint64
+	// DefaultSubSourceID holds the default value on creation for the "sub_source_id" field.
+	DefaultSubSourceID uint64
+)
+
+// OrderOption defines the ordering options for the MessageRecords queries.
+type OrderOption func(*sql.Selector)
+
+// ByID orders the results by the id field.
+func ByID(opts ...sql.OrderTermOption) OrderOption {
+	return sql.OrderByField(FieldID, opts...).ToFunc()
+}
+
+// ByCreatedAt orders the results by the created_at field.
+func ByCreatedAt(opts ...sql.OrderTermOption) OrderOption {
+	return sql.OrderByField(FieldCreatedAt, opts...).ToFunc()
+}
+
+// ByUpdatedAt orders the results by the updated_at field.
+func ByUpdatedAt(opts ...sql.OrderTermOption) OrderOption {
+	return sql.OrderByField(FieldUpdatedAt, opts...).ToFunc()
+}
+
+// ByStatus orders the results by the status field.
+func ByStatus(opts ...sql.OrderTermOption) OrderOption {
+	return sql.OrderByField(FieldStatus, opts...).ToFunc()
+}
+
+// ByBotWxid orders the results by the bot_wxid field.
+func ByBotWxid(opts ...sql.OrderTermOption) OrderOption {
+	return sql.OrderByField(FieldBotWxid, opts...).ToFunc()
+}
+
+// ByContactID orders the results by the contact_id field.
+func ByContactID(opts ...sql.OrderTermOption) OrderOption {
+	return sql.OrderByField(FieldContactID, opts...).ToFunc()
+}
+
+// ByContactType orders the results by the contact_type field.
+func ByContactType(opts ...sql.OrderTermOption) OrderOption {
+	return sql.OrderByField(FieldContactType, opts...).ToFunc()
+}
+
+// ByContactWxid orders the results by the contact_wxid field.
+func ByContactWxid(opts ...sql.OrderTermOption) OrderOption {
+	return sql.OrderByField(FieldContactWxid, opts...).ToFunc()
+}
+
+// ByContentType orders the results by the content_type field.
+func ByContentType(opts ...sql.OrderTermOption) OrderOption {
+	return sql.OrderByField(FieldContentType, opts...).ToFunc()
+}
+
+// ByContent orders the results by the content field.
+func ByContent(opts ...sql.OrderTermOption) OrderOption {
+	return sql.OrderByField(FieldContent, opts...).ToFunc()
+}
+
+// ByErrorDetail orders the results by the error_detail field.
+func ByErrorDetail(opts ...sql.OrderTermOption) OrderOption {
+	return sql.OrderByField(FieldErrorDetail, opts...).ToFunc()
+}
+
+// BySendTime orders the results by the send_time field.
+func BySendTime(opts ...sql.OrderTermOption) OrderOption {
+	return sql.OrderByField(FieldSendTime, opts...).ToFunc()
+}
+
+// BySourceType orders the results by the source_type field.
+func BySourceType(opts ...sql.OrderTermOption) OrderOption {
+	return sql.OrderByField(FieldSourceType, opts...).ToFunc()
+}
+
+// BySourceID orders the results by the source_id field.
+func BySourceID(opts ...sql.OrderTermOption) OrderOption {
+	return sql.OrderByField(FieldSourceID, opts...).ToFunc()
+}
+
+// BySubSourceID orders the results by the sub_source_id field.
+func BySubSourceID(opts ...sql.OrderTermOption) OrderOption {
+	return sql.OrderByField(FieldSubSourceID, opts...).ToFunc()
+}

+ 850 - 0
ent/messagerecords/where.go

@@ -0,0 +1,850 @@
+// Code generated by ent, DO NOT EDIT.
+
+package messagerecords
+
+import (
+	"time"
+
+	"entgo.io/ent/dialect/sql"
+	"github.com/suyuan32/simple-admin-job/ent/predicate"
+)
+
+// ID filters vertices based on their ID field.
+func ID(id uint64) predicate.MessageRecords {
+	return predicate.MessageRecords(sql.FieldEQ(FieldID, id))
+}
+
+// IDEQ applies the EQ predicate on the ID field.
+func IDEQ(id uint64) predicate.MessageRecords {
+	return predicate.MessageRecords(sql.FieldEQ(FieldID, id))
+}
+
+// IDNEQ applies the NEQ predicate on the ID field.
+func IDNEQ(id uint64) predicate.MessageRecords {
+	return predicate.MessageRecords(sql.FieldNEQ(FieldID, id))
+}
+
+// IDIn applies the In predicate on the ID field.
+func IDIn(ids ...uint64) predicate.MessageRecords {
+	return predicate.MessageRecords(sql.FieldIn(FieldID, ids...))
+}
+
+// IDNotIn applies the NotIn predicate on the ID field.
+func IDNotIn(ids ...uint64) predicate.MessageRecords {
+	return predicate.MessageRecords(sql.FieldNotIn(FieldID, ids...))
+}
+
+// IDGT applies the GT predicate on the ID field.
+func IDGT(id uint64) predicate.MessageRecords {
+	return predicate.MessageRecords(sql.FieldGT(FieldID, id))
+}
+
+// IDGTE applies the GTE predicate on the ID field.
+func IDGTE(id uint64) predicate.MessageRecords {
+	return predicate.MessageRecords(sql.FieldGTE(FieldID, id))
+}
+
+// IDLT applies the LT predicate on the ID field.
+func IDLT(id uint64) predicate.MessageRecords {
+	return predicate.MessageRecords(sql.FieldLT(FieldID, id))
+}
+
+// IDLTE applies the LTE predicate on the ID field.
+func IDLTE(id uint64) predicate.MessageRecords {
+	return predicate.MessageRecords(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.MessageRecords {
+	return predicate.MessageRecords(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.MessageRecords {
+	return predicate.MessageRecords(sql.FieldEQ(FieldUpdatedAt, v))
+}
+
+// Status applies equality check predicate on the "status" field. It's identical to StatusEQ.
+func Status(v uint8) predicate.MessageRecords {
+	return predicate.MessageRecords(sql.FieldEQ(FieldStatus, v))
+}
+
+// BotWxid applies equality check predicate on the "bot_wxid" field. It's identical to BotWxidEQ.
+func BotWxid(v string) predicate.MessageRecords {
+	return predicate.MessageRecords(sql.FieldEQ(FieldBotWxid, v))
+}
+
+// ContactID applies equality check predicate on the "contact_id" field. It's identical to ContactIDEQ.
+func ContactID(v uint64) predicate.MessageRecords {
+	return predicate.MessageRecords(sql.FieldEQ(FieldContactID, v))
+}
+
+// ContactType applies equality check predicate on the "contact_type" field. It's identical to ContactTypeEQ.
+func ContactType(v int) predicate.MessageRecords {
+	return predicate.MessageRecords(sql.FieldEQ(FieldContactType, v))
+}
+
+// ContactWxid applies equality check predicate on the "contact_wxid" field. It's identical to ContactWxidEQ.
+func ContactWxid(v string) predicate.MessageRecords {
+	return predicate.MessageRecords(sql.FieldEQ(FieldContactWxid, v))
+}
+
+// ContentType applies equality check predicate on the "content_type" field. It's identical to ContentTypeEQ.
+func ContentType(v int) predicate.MessageRecords {
+	return predicate.MessageRecords(sql.FieldEQ(FieldContentType, v))
+}
+
+// Content applies equality check predicate on the "content" field. It's identical to ContentEQ.
+func Content(v string) predicate.MessageRecords {
+	return predicate.MessageRecords(sql.FieldEQ(FieldContent, v))
+}
+
+// ErrorDetail applies equality check predicate on the "error_detail" field. It's identical to ErrorDetailEQ.
+func ErrorDetail(v string) predicate.MessageRecords {
+	return predicate.MessageRecords(sql.FieldEQ(FieldErrorDetail, v))
+}
+
+// SendTime applies equality check predicate on the "send_time" field. It's identical to SendTimeEQ.
+func SendTime(v time.Time) predicate.MessageRecords {
+	return predicate.MessageRecords(sql.FieldEQ(FieldSendTime, v))
+}
+
+// SourceType applies equality check predicate on the "source_type" field. It's identical to SourceTypeEQ.
+func SourceType(v int) predicate.MessageRecords {
+	return predicate.MessageRecords(sql.FieldEQ(FieldSourceType, v))
+}
+
+// SourceID applies equality check predicate on the "source_id" field. It's identical to SourceIDEQ.
+func SourceID(v uint64) predicate.MessageRecords {
+	return predicate.MessageRecords(sql.FieldEQ(FieldSourceID, v))
+}
+
+// SubSourceID applies equality check predicate on the "sub_source_id" field. It's identical to SubSourceIDEQ.
+func SubSourceID(v uint64) predicate.MessageRecords {
+	return predicate.MessageRecords(sql.FieldEQ(FieldSubSourceID, v))
+}
+
+// CreatedAtEQ applies the EQ predicate on the "created_at" field.
+func CreatedAtEQ(v time.Time) predicate.MessageRecords {
+	return predicate.MessageRecords(sql.FieldEQ(FieldCreatedAt, v))
+}
+
+// CreatedAtNEQ applies the NEQ predicate on the "created_at" field.
+func CreatedAtNEQ(v time.Time) predicate.MessageRecords {
+	return predicate.MessageRecords(sql.FieldNEQ(FieldCreatedAt, v))
+}
+
+// CreatedAtIn applies the In predicate on the "created_at" field.
+func CreatedAtIn(vs ...time.Time) predicate.MessageRecords {
+	return predicate.MessageRecords(sql.FieldIn(FieldCreatedAt, vs...))
+}
+
+// CreatedAtNotIn applies the NotIn predicate on the "created_at" field.
+func CreatedAtNotIn(vs ...time.Time) predicate.MessageRecords {
+	return predicate.MessageRecords(sql.FieldNotIn(FieldCreatedAt, vs...))
+}
+
+// CreatedAtGT applies the GT predicate on the "created_at" field.
+func CreatedAtGT(v time.Time) predicate.MessageRecords {
+	return predicate.MessageRecords(sql.FieldGT(FieldCreatedAt, v))
+}
+
+// CreatedAtGTE applies the GTE predicate on the "created_at" field.
+func CreatedAtGTE(v time.Time) predicate.MessageRecords {
+	return predicate.MessageRecords(sql.FieldGTE(FieldCreatedAt, v))
+}
+
+// CreatedAtLT applies the LT predicate on the "created_at" field.
+func CreatedAtLT(v time.Time) predicate.MessageRecords {
+	return predicate.MessageRecords(sql.FieldLT(FieldCreatedAt, v))
+}
+
+// CreatedAtLTE applies the LTE predicate on the "created_at" field.
+func CreatedAtLTE(v time.Time) predicate.MessageRecords {
+	return predicate.MessageRecords(sql.FieldLTE(FieldCreatedAt, v))
+}
+
+// UpdatedAtEQ applies the EQ predicate on the "updated_at" field.
+func UpdatedAtEQ(v time.Time) predicate.MessageRecords {
+	return predicate.MessageRecords(sql.FieldEQ(FieldUpdatedAt, v))
+}
+
+// UpdatedAtNEQ applies the NEQ predicate on the "updated_at" field.
+func UpdatedAtNEQ(v time.Time) predicate.MessageRecords {
+	return predicate.MessageRecords(sql.FieldNEQ(FieldUpdatedAt, v))
+}
+
+// UpdatedAtIn applies the In predicate on the "updated_at" field.
+func UpdatedAtIn(vs ...time.Time) predicate.MessageRecords {
+	return predicate.MessageRecords(sql.FieldIn(FieldUpdatedAt, vs...))
+}
+
+// UpdatedAtNotIn applies the NotIn predicate on the "updated_at" field.
+func UpdatedAtNotIn(vs ...time.Time) predicate.MessageRecords {
+	return predicate.MessageRecords(sql.FieldNotIn(FieldUpdatedAt, vs...))
+}
+
+// UpdatedAtGT applies the GT predicate on the "updated_at" field.
+func UpdatedAtGT(v time.Time) predicate.MessageRecords {
+	return predicate.MessageRecords(sql.FieldGT(FieldUpdatedAt, v))
+}
+
+// UpdatedAtGTE applies the GTE predicate on the "updated_at" field.
+func UpdatedAtGTE(v time.Time) predicate.MessageRecords {
+	return predicate.MessageRecords(sql.FieldGTE(FieldUpdatedAt, v))
+}
+
+// UpdatedAtLT applies the LT predicate on the "updated_at" field.
+func UpdatedAtLT(v time.Time) predicate.MessageRecords {
+	return predicate.MessageRecords(sql.FieldLT(FieldUpdatedAt, v))
+}
+
+// UpdatedAtLTE applies the LTE predicate on the "updated_at" field.
+func UpdatedAtLTE(v time.Time) predicate.MessageRecords {
+	return predicate.MessageRecords(sql.FieldLTE(FieldUpdatedAt, v))
+}
+
+// StatusEQ applies the EQ predicate on the "status" field.
+func StatusEQ(v uint8) predicate.MessageRecords {
+	return predicate.MessageRecords(sql.FieldEQ(FieldStatus, v))
+}
+
+// StatusNEQ applies the NEQ predicate on the "status" field.
+func StatusNEQ(v uint8) predicate.MessageRecords {
+	return predicate.MessageRecords(sql.FieldNEQ(FieldStatus, v))
+}
+
+// StatusIn applies the In predicate on the "status" field.
+func StatusIn(vs ...uint8) predicate.MessageRecords {
+	return predicate.MessageRecords(sql.FieldIn(FieldStatus, vs...))
+}
+
+// StatusNotIn applies the NotIn predicate on the "status" field.
+func StatusNotIn(vs ...uint8) predicate.MessageRecords {
+	return predicate.MessageRecords(sql.FieldNotIn(FieldStatus, vs...))
+}
+
+// StatusGT applies the GT predicate on the "status" field.
+func StatusGT(v uint8) predicate.MessageRecords {
+	return predicate.MessageRecords(sql.FieldGT(FieldStatus, v))
+}
+
+// StatusGTE applies the GTE predicate on the "status" field.
+func StatusGTE(v uint8) predicate.MessageRecords {
+	return predicate.MessageRecords(sql.FieldGTE(FieldStatus, v))
+}
+
+// StatusLT applies the LT predicate on the "status" field.
+func StatusLT(v uint8) predicate.MessageRecords {
+	return predicate.MessageRecords(sql.FieldLT(FieldStatus, v))
+}
+
+// StatusLTE applies the LTE predicate on the "status" field.
+func StatusLTE(v uint8) predicate.MessageRecords {
+	return predicate.MessageRecords(sql.FieldLTE(FieldStatus, v))
+}
+
+// StatusIsNil applies the IsNil predicate on the "status" field.
+func StatusIsNil() predicate.MessageRecords {
+	return predicate.MessageRecords(sql.FieldIsNull(FieldStatus))
+}
+
+// StatusNotNil applies the NotNil predicate on the "status" field.
+func StatusNotNil() predicate.MessageRecords {
+	return predicate.MessageRecords(sql.FieldNotNull(FieldStatus))
+}
+
+// BotWxidEQ applies the EQ predicate on the "bot_wxid" field.
+func BotWxidEQ(v string) predicate.MessageRecords {
+	return predicate.MessageRecords(sql.FieldEQ(FieldBotWxid, v))
+}
+
+// BotWxidNEQ applies the NEQ predicate on the "bot_wxid" field.
+func BotWxidNEQ(v string) predicate.MessageRecords {
+	return predicate.MessageRecords(sql.FieldNEQ(FieldBotWxid, v))
+}
+
+// BotWxidIn applies the In predicate on the "bot_wxid" field.
+func BotWxidIn(vs ...string) predicate.MessageRecords {
+	return predicate.MessageRecords(sql.FieldIn(FieldBotWxid, vs...))
+}
+
+// BotWxidNotIn applies the NotIn predicate on the "bot_wxid" field.
+func BotWxidNotIn(vs ...string) predicate.MessageRecords {
+	return predicate.MessageRecords(sql.FieldNotIn(FieldBotWxid, vs...))
+}
+
+// BotWxidGT applies the GT predicate on the "bot_wxid" field.
+func BotWxidGT(v string) predicate.MessageRecords {
+	return predicate.MessageRecords(sql.FieldGT(FieldBotWxid, v))
+}
+
+// BotWxidGTE applies the GTE predicate on the "bot_wxid" field.
+func BotWxidGTE(v string) predicate.MessageRecords {
+	return predicate.MessageRecords(sql.FieldGTE(FieldBotWxid, v))
+}
+
+// BotWxidLT applies the LT predicate on the "bot_wxid" field.
+func BotWxidLT(v string) predicate.MessageRecords {
+	return predicate.MessageRecords(sql.FieldLT(FieldBotWxid, v))
+}
+
+// BotWxidLTE applies the LTE predicate on the "bot_wxid" field.
+func BotWxidLTE(v string) predicate.MessageRecords {
+	return predicate.MessageRecords(sql.FieldLTE(FieldBotWxid, v))
+}
+
+// BotWxidContains applies the Contains predicate on the "bot_wxid" field.
+func BotWxidContains(v string) predicate.MessageRecords {
+	return predicate.MessageRecords(sql.FieldContains(FieldBotWxid, v))
+}
+
+// BotWxidHasPrefix applies the HasPrefix predicate on the "bot_wxid" field.
+func BotWxidHasPrefix(v string) predicate.MessageRecords {
+	return predicate.MessageRecords(sql.FieldHasPrefix(FieldBotWxid, v))
+}
+
+// BotWxidHasSuffix applies the HasSuffix predicate on the "bot_wxid" field.
+func BotWxidHasSuffix(v string) predicate.MessageRecords {
+	return predicate.MessageRecords(sql.FieldHasSuffix(FieldBotWxid, v))
+}
+
+// BotWxidEqualFold applies the EqualFold predicate on the "bot_wxid" field.
+func BotWxidEqualFold(v string) predicate.MessageRecords {
+	return predicate.MessageRecords(sql.FieldEqualFold(FieldBotWxid, v))
+}
+
+// BotWxidContainsFold applies the ContainsFold predicate on the "bot_wxid" field.
+func BotWxidContainsFold(v string) predicate.MessageRecords {
+	return predicate.MessageRecords(sql.FieldContainsFold(FieldBotWxid, v))
+}
+
+// ContactIDEQ applies the EQ predicate on the "contact_id" field.
+func ContactIDEQ(v uint64) predicate.MessageRecords {
+	return predicate.MessageRecords(sql.FieldEQ(FieldContactID, v))
+}
+
+// ContactIDNEQ applies the NEQ predicate on the "contact_id" field.
+func ContactIDNEQ(v uint64) predicate.MessageRecords {
+	return predicate.MessageRecords(sql.FieldNEQ(FieldContactID, v))
+}
+
+// ContactIDIn applies the In predicate on the "contact_id" field.
+func ContactIDIn(vs ...uint64) predicate.MessageRecords {
+	return predicate.MessageRecords(sql.FieldIn(FieldContactID, vs...))
+}
+
+// ContactIDNotIn applies the NotIn predicate on the "contact_id" field.
+func ContactIDNotIn(vs ...uint64) predicate.MessageRecords {
+	return predicate.MessageRecords(sql.FieldNotIn(FieldContactID, vs...))
+}
+
+// ContactIDGT applies the GT predicate on the "contact_id" field.
+func ContactIDGT(v uint64) predicate.MessageRecords {
+	return predicate.MessageRecords(sql.FieldGT(FieldContactID, v))
+}
+
+// ContactIDGTE applies the GTE predicate on the "contact_id" field.
+func ContactIDGTE(v uint64) predicate.MessageRecords {
+	return predicate.MessageRecords(sql.FieldGTE(FieldContactID, v))
+}
+
+// ContactIDLT applies the LT predicate on the "contact_id" field.
+func ContactIDLT(v uint64) predicate.MessageRecords {
+	return predicate.MessageRecords(sql.FieldLT(FieldContactID, v))
+}
+
+// ContactIDLTE applies the LTE predicate on the "contact_id" field.
+func ContactIDLTE(v uint64) predicate.MessageRecords {
+	return predicate.MessageRecords(sql.FieldLTE(FieldContactID, v))
+}
+
+// ContactIDIsNil applies the IsNil predicate on the "contact_id" field.
+func ContactIDIsNil() predicate.MessageRecords {
+	return predicate.MessageRecords(sql.FieldIsNull(FieldContactID))
+}
+
+// ContactIDNotNil applies the NotNil predicate on the "contact_id" field.
+func ContactIDNotNil() predicate.MessageRecords {
+	return predicate.MessageRecords(sql.FieldNotNull(FieldContactID))
+}
+
+// ContactTypeEQ applies the EQ predicate on the "contact_type" field.
+func ContactTypeEQ(v int) predicate.MessageRecords {
+	return predicate.MessageRecords(sql.FieldEQ(FieldContactType, v))
+}
+
+// ContactTypeNEQ applies the NEQ predicate on the "contact_type" field.
+func ContactTypeNEQ(v int) predicate.MessageRecords {
+	return predicate.MessageRecords(sql.FieldNEQ(FieldContactType, v))
+}
+
+// ContactTypeIn applies the In predicate on the "contact_type" field.
+func ContactTypeIn(vs ...int) predicate.MessageRecords {
+	return predicate.MessageRecords(sql.FieldIn(FieldContactType, vs...))
+}
+
+// ContactTypeNotIn applies the NotIn predicate on the "contact_type" field.
+func ContactTypeNotIn(vs ...int) predicate.MessageRecords {
+	return predicate.MessageRecords(sql.FieldNotIn(FieldContactType, vs...))
+}
+
+// ContactTypeGT applies the GT predicate on the "contact_type" field.
+func ContactTypeGT(v int) predicate.MessageRecords {
+	return predicate.MessageRecords(sql.FieldGT(FieldContactType, v))
+}
+
+// ContactTypeGTE applies the GTE predicate on the "contact_type" field.
+func ContactTypeGTE(v int) predicate.MessageRecords {
+	return predicate.MessageRecords(sql.FieldGTE(FieldContactType, v))
+}
+
+// ContactTypeLT applies the LT predicate on the "contact_type" field.
+func ContactTypeLT(v int) predicate.MessageRecords {
+	return predicate.MessageRecords(sql.FieldLT(FieldContactType, v))
+}
+
+// ContactTypeLTE applies the LTE predicate on the "contact_type" field.
+func ContactTypeLTE(v int) predicate.MessageRecords {
+	return predicate.MessageRecords(sql.FieldLTE(FieldContactType, v))
+}
+
+// ContactWxidEQ applies the EQ predicate on the "contact_wxid" field.
+func ContactWxidEQ(v string) predicate.MessageRecords {
+	return predicate.MessageRecords(sql.FieldEQ(FieldContactWxid, v))
+}
+
+// ContactWxidNEQ applies the NEQ predicate on the "contact_wxid" field.
+func ContactWxidNEQ(v string) predicate.MessageRecords {
+	return predicate.MessageRecords(sql.FieldNEQ(FieldContactWxid, v))
+}
+
+// ContactWxidIn applies the In predicate on the "contact_wxid" field.
+func ContactWxidIn(vs ...string) predicate.MessageRecords {
+	return predicate.MessageRecords(sql.FieldIn(FieldContactWxid, vs...))
+}
+
+// ContactWxidNotIn applies the NotIn predicate on the "contact_wxid" field.
+func ContactWxidNotIn(vs ...string) predicate.MessageRecords {
+	return predicate.MessageRecords(sql.FieldNotIn(FieldContactWxid, vs...))
+}
+
+// ContactWxidGT applies the GT predicate on the "contact_wxid" field.
+func ContactWxidGT(v string) predicate.MessageRecords {
+	return predicate.MessageRecords(sql.FieldGT(FieldContactWxid, v))
+}
+
+// ContactWxidGTE applies the GTE predicate on the "contact_wxid" field.
+func ContactWxidGTE(v string) predicate.MessageRecords {
+	return predicate.MessageRecords(sql.FieldGTE(FieldContactWxid, v))
+}
+
+// ContactWxidLT applies the LT predicate on the "contact_wxid" field.
+func ContactWxidLT(v string) predicate.MessageRecords {
+	return predicate.MessageRecords(sql.FieldLT(FieldContactWxid, v))
+}
+
+// ContactWxidLTE applies the LTE predicate on the "contact_wxid" field.
+func ContactWxidLTE(v string) predicate.MessageRecords {
+	return predicate.MessageRecords(sql.FieldLTE(FieldContactWxid, v))
+}
+
+// ContactWxidContains applies the Contains predicate on the "contact_wxid" field.
+func ContactWxidContains(v string) predicate.MessageRecords {
+	return predicate.MessageRecords(sql.FieldContains(FieldContactWxid, v))
+}
+
+// ContactWxidHasPrefix applies the HasPrefix predicate on the "contact_wxid" field.
+func ContactWxidHasPrefix(v string) predicate.MessageRecords {
+	return predicate.MessageRecords(sql.FieldHasPrefix(FieldContactWxid, v))
+}
+
+// ContactWxidHasSuffix applies the HasSuffix predicate on the "contact_wxid" field.
+func ContactWxidHasSuffix(v string) predicate.MessageRecords {
+	return predicate.MessageRecords(sql.FieldHasSuffix(FieldContactWxid, v))
+}
+
+// ContactWxidEqualFold applies the EqualFold predicate on the "contact_wxid" field.
+func ContactWxidEqualFold(v string) predicate.MessageRecords {
+	return predicate.MessageRecords(sql.FieldEqualFold(FieldContactWxid, v))
+}
+
+// ContactWxidContainsFold applies the ContainsFold predicate on the "contact_wxid" field.
+func ContactWxidContainsFold(v string) predicate.MessageRecords {
+	return predicate.MessageRecords(sql.FieldContainsFold(FieldContactWxid, v))
+}
+
+// ContentTypeEQ applies the EQ predicate on the "content_type" field.
+func ContentTypeEQ(v int) predicate.MessageRecords {
+	return predicate.MessageRecords(sql.FieldEQ(FieldContentType, v))
+}
+
+// ContentTypeNEQ applies the NEQ predicate on the "content_type" field.
+func ContentTypeNEQ(v int) predicate.MessageRecords {
+	return predicate.MessageRecords(sql.FieldNEQ(FieldContentType, v))
+}
+
+// ContentTypeIn applies the In predicate on the "content_type" field.
+func ContentTypeIn(vs ...int) predicate.MessageRecords {
+	return predicate.MessageRecords(sql.FieldIn(FieldContentType, vs...))
+}
+
+// ContentTypeNotIn applies the NotIn predicate on the "content_type" field.
+func ContentTypeNotIn(vs ...int) predicate.MessageRecords {
+	return predicate.MessageRecords(sql.FieldNotIn(FieldContentType, vs...))
+}
+
+// ContentTypeGT applies the GT predicate on the "content_type" field.
+func ContentTypeGT(v int) predicate.MessageRecords {
+	return predicate.MessageRecords(sql.FieldGT(FieldContentType, v))
+}
+
+// ContentTypeGTE applies the GTE predicate on the "content_type" field.
+func ContentTypeGTE(v int) predicate.MessageRecords {
+	return predicate.MessageRecords(sql.FieldGTE(FieldContentType, v))
+}
+
+// ContentTypeLT applies the LT predicate on the "content_type" field.
+func ContentTypeLT(v int) predicate.MessageRecords {
+	return predicate.MessageRecords(sql.FieldLT(FieldContentType, v))
+}
+
+// ContentTypeLTE applies the LTE predicate on the "content_type" field.
+func ContentTypeLTE(v int) predicate.MessageRecords {
+	return predicate.MessageRecords(sql.FieldLTE(FieldContentType, v))
+}
+
+// ContentEQ applies the EQ predicate on the "content" field.
+func ContentEQ(v string) predicate.MessageRecords {
+	return predicate.MessageRecords(sql.FieldEQ(FieldContent, v))
+}
+
+// ContentNEQ applies the NEQ predicate on the "content" field.
+func ContentNEQ(v string) predicate.MessageRecords {
+	return predicate.MessageRecords(sql.FieldNEQ(FieldContent, v))
+}
+
+// ContentIn applies the In predicate on the "content" field.
+func ContentIn(vs ...string) predicate.MessageRecords {
+	return predicate.MessageRecords(sql.FieldIn(FieldContent, vs...))
+}
+
+// ContentNotIn applies the NotIn predicate on the "content" field.
+func ContentNotIn(vs ...string) predicate.MessageRecords {
+	return predicate.MessageRecords(sql.FieldNotIn(FieldContent, vs...))
+}
+
+// ContentGT applies the GT predicate on the "content" field.
+func ContentGT(v string) predicate.MessageRecords {
+	return predicate.MessageRecords(sql.FieldGT(FieldContent, v))
+}
+
+// ContentGTE applies the GTE predicate on the "content" field.
+func ContentGTE(v string) predicate.MessageRecords {
+	return predicate.MessageRecords(sql.FieldGTE(FieldContent, v))
+}
+
+// ContentLT applies the LT predicate on the "content" field.
+func ContentLT(v string) predicate.MessageRecords {
+	return predicate.MessageRecords(sql.FieldLT(FieldContent, v))
+}
+
+// ContentLTE applies the LTE predicate on the "content" field.
+func ContentLTE(v string) predicate.MessageRecords {
+	return predicate.MessageRecords(sql.FieldLTE(FieldContent, v))
+}
+
+// ContentContains applies the Contains predicate on the "content" field.
+func ContentContains(v string) predicate.MessageRecords {
+	return predicate.MessageRecords(sql.FieldContains(FieldContent, v))
+}
+
+// ContentHasPrefix applies the HasPrefix predicate on the "content" field.
+func ContentHasPrefix(v string) predicate.MessageRecords {
+	return predicate.MessageRecords(sql.FieldHasPrefix(FieldContent, v))
+}
+
+// ContentHasSuffix applies the HasSuffix predicate on the "content" field.
+func ContentHasSuffix(v string) predicate.MessageRecords {
+	return predicate.MessageRecords(sql.FieldHasSuffix(FieldContent, v))
+}
+
+// ContentEqualFold applies the EqualFold predicate on the "content" field.
+func ContentEqualFold(v string) predicate.MessageRecords {
+	return predicate.MessageRecords(sql.FieldEqualFold(FieldContent, v))
+}
+
+// ContentContainsFold applies the ContainsFold predicate on the "content" field.
+func ContentContainsFold(v string) predicate.MessageRecords {
+	return predicate.MessageRecords(sql.FieldContainsFold(FieldContent, v))
+}
+
+// ErrorDetailEQ applies the EQ predicate on the "error_detail" field.
+func ErrorDetailEQ(v string) predicate.MessageRecords {
+	return predicate.MessageRecords(sql.FieldEQ(FieldErrorDetail, v))
+}
+
+// ErrorDetailNEQ applies the NEQ predicate on the "error_detail" field.
+func ErrorDetailNEQ(v string) predicate.MessageRecords {
+	return predicate.MessageRecords(sql.FieldNEQ(FieldErrorDetail, v))
+}
+
+// ErrorDetailIn applies the In predicate on the "error_detail" field.
+func ErrorDetailIn(vs ...string) predicate.MessageRecords {
+	return predicate.MessageRecords(sql.FieldIn(FieldErrorDetail, vs...))
+}
+
+// ErrorDetailNotIn applies the NotIn predicate on the "error_detail" field.
+func ErrorDetailNotIn(vs ...string) predicate.MessageRecords {
+	return predicate.MessageRecords(sql.FieldNotIn(FieldErrorDetail, vs...))
+}
+
+// ErrorDetailGT applies the GT predicate on the "error_detail" field.
+func ErrorDetailGT(v string) predicate.MessageRecords {
+	return predicate.MessageRecords(sql.FieldGT(FieldErrorDetail, v))
+}
+
+// ErrorDetailGTE applies the GTE predicate on the "error_detail" field.
+func ErrorDetailGTE(v string) predicate.MessageRecords {
+	return predicate.MessageRecords(sql.FieldGTE(FieldErrorDetail, v))
+}
+
+// ErrorDetailLT applies the LT predicate on the "error_detail" field.
+func ErrorDetailLT(v string) predicate.MessageRecords {
+	return predicate.MessageRecords(sql.FieldLT(FieldErrorDetail, v))
+}
+
+// ErrorDetailLTE applies the LTE predicate on the "error_detail" field.
+func ErrorDetailLTE(v string) predicate.MessageRecords {
+	return predicate.MessageRecords(sql.FieldLTE(FieldErrorDetail, v))
+}
+
+// ErrorDetailContains applies the Contains predicate on the "error_detail" field.
+func ErrorDetailContains(v string) predicate.MessageRecords {
+	return predicate.MessageRecords(sql.FieldContains(FieldErrorDetail, v))
+}
+
+// ErrorDetailHasPrefix applies the HasPrefix predicate on the "error_detail" field.
+func ErrorDetailHasPrefix(v string) predicate.MessageRecords {
+	return predicate.MessageRecords(sql.FieldHasPrefix(FieldErrorDetail, v))
+}
+
+// ErrorDetailHasSuffix applies the HasSuffix predicate on the "error_detail" field.
+func ErrorDetailHasSuffix(v string) predicate.MessageRecords {
+	return predicate.MessageRecords(sql.FieldHasSuffix(FieldErrorDetail, v))
+}
+
+// ErrorDetailEqualFold applies the EqualFold predicate on the "error_detail" field.
+func ErrorDetailEqualFold(v string) predicate.MessageRecords {
+	return predicate.MessageRecords(sql.FieldEqualFold(FieldErrorDetail, v))
+}
+
+// ErrorDetailContainsFold applies the ContainsFold predicate on the "error_detail" field.
+func ErrorDetailContainsFold(v string) predicate.MessageRecords {
+	return predicate.MessageRecords(sql.FieldContainsFold(FieldErrorDetail, v))
+}
+
+// SendTimeEQ applies the EQ predicate on the "send_time" field.
+func SendTimeEQ(v time.Time) predicate.MessageRecords {
+	return predicate.MessageRecords(sql.FieldEQ(FieldSendTime, v))
+}
+
+// SendTimeNEQ applies the NEQ predicate on the "send_time" field.
+func SendTimeNEQ(v time.Time) predicate.MessageRecords {
+	return predicate.MessageRecords(sql.FieldNEQ(FieldSendTime, v))
+}
+
+// SendTimeIn applies the In predicate on the "send_time" field.
+func SendTimeIn(vs ...time.Time) predicate.MessageRecords {
+	return predicate.MessageRecords(sql.FieldIn(FieldSendTime, vs...))
+}
+
+// SendTimeNotIn applies the NotIn predicate on the "send_time" field.
+func SendTimeNotIn(vs ...time.Time) predicate.MessageRecords {
+	return predicate.MessageRecords(sql.FieldNotIn(FieldSendTime, vs...))
+}
+
+// SendTimeGT applies the GT predicate on the "send_time" field.
+func SendTimeGT(v time.Time) predicate.MessageRecords {
+	return predicate.MessageRecords(sql.FieldGT(FieldSendTime, v))
+}
+
+// SendTimeGTE applies the GTE predicate on the "send_time" field.
+func SendTimeGTE(v time.Time) predicate.MessageRecords {
+	return predicate.MessageRecords(sql.FieldGTE(FieldSendTime, v))
+}
+
+// SendTimeLT applies the LT predicate on the "send_time" field.
+func SendTimeLT(v time.Time) predicate.MessageRecords {
+	return predicate.MessageRecords(sql.FieldLT(FieldSendTime, v))
+}
+
+// SendTimeLTE applies the LTE predicate on the "send_time" field.
+func SendTimeLTE(v time.Time) predicate.MessageRecords {
+	return predicate.MessageRecords(sql.FieldLTE(FieldSendTime, v))
+}
+
+// SendTimeIsNil applies the IsNil predicate on the "send_time" field.
+func SendTimeIsNil() predicate.MessageRecords {
+	return predicate.MessageRecords(sql.FieldIsNull(FieldSendTime))
+}
+
+// SendTimeNotNil applies the NotNil predicate on the "send_time" field.
+func SendTimeNotNil() predicate.MessageRecords {
+	return predicate.MessageRecords(sql.FieldNotNull(FieldSendTime))
+}
+
+// SourceTypeEQ applies the EQ predicate on the "source_type" field.
+func SourceTypeEQ(v int) predicate.MessageRecords {
+	return predicate.MessageRecords(sql.FieldEQ(FieldSourceType, v))
+}
+
+// SourceTypeNEQ applies the NEQ predicate on the "source_type" field.
+func SourceTypeNEQ(v int) predicate.MessageRecords {
+	return predicate.MessageRecords(sql.FieldNEQ(FieldSourceType, v))
+}
+
+// SourceTypeIn applies the In predicate on the "source_type" field.
+func SourceTypeIn(vs ...int) predicate.MessageRecords {
+	return predicate.MessageRecords(sql.FieldIn(FieldSourceType, vs...))
+}
+
+// SourceTypeNotIn applies the NotIn predicate on the "source_type" field.
+func SourceTypeNotIn(vs ...int) predicate.MessageRecords {
+	return predicate.MessageRecords(sql.FieldNotIn(FieldSourceType, vs...))
+}
+
+// SourceTypeGT applies the GT predicate on the "source_type" field.
+func SourceTypeGT(v int) predicate.MessageRecords {
+	return predicate.MessageRecords(sql.FieldGT(FieldSourceType, v))
+}
+
+// SourceTypeGTE applies the GTE predicate on the "source_type" field.
+func SourceTypeGTE(v int) predicate.MessageRecords {
+	return predicate.MessageRecords(sql.FieldGTE(FieldSourceType, v))
+}
+
+// SourceTypeLT applies the LT predicate on the "source_type" field.
+func SourceTypeLT(v int) predicate.MessageRecords {
+	return predicate.MessageRecords(sql.FieldLT(FieldSourceType, v))
+}
+
+// SourceTypeLTE applies the LTE predicate on the "source_type" field.
+func SourceTypeLTE(v int) predicate.MessageRecords {
+	return predicate.MessageRecords(sql.FieldLTE(FieldSourceType, v))
+}
+
+// SourceIDEQ applies the EQ predicate on the "source_id" field.
+func SourceIDEQ(v uint64) predicate.MessageRecords {
+	return predicate.MessageRecords(sql.FieldEQ(FieldSourceID, v))
+}
+
+// SourceIDNEQ applies the NEQ predicate on the "source_id" field.
+func SourceIDNEQ(v uint64) predicate.MessageRecords {
+	return predicate.MessageRecords(sql.FieldNEQ(FieldSourceID, v))
+}
+
+// SourceIDIn applies the In predicate on the "source_id" field.
+func SourceIDIn(vs ...uint64) predicate.MessageRecords {
+	return predicate.MessageRecords(sql.FieldIn(FieldSourceID, vs...))
+}
+
+// SourceIDNotIn applies the NotIn predicate on the "source_id" field.
+func SourceIDNotIn(vs ...uint64) predicate.MessageRecords {
+	return predicate.MessageRecords(sql.FieldNotIn(FieldSourceID, vs...))
+}
+
+// SourceIDGT applies the GT predicate on the "source_id" field.
+func SourceIDGT(v uint64) predicate.MessageRecords {
+	return predicate.MessageRecords(sql.FieldGT(FieldSourceID, v))
+}
+
+// SourceIDGTE applies the GTE predicate on the "source_id" field.
+func SourceIDGTE(v uint64) predicate.MessageRecords {
+	return predicate.MessageRecords(sql.FieldGTE(FieldSourceID, v))
+}
+
+// SourceIDLT applies the LT predicate on the "source_id" field.
+func SourceIDLT(v uint64) predicate.MessageRecords {
+	return predicate.MessageRecords(sql.FieldLT(FieldSourceID, v))
+}
+
+// SourceIDLTE applies the LTE predicate on the "source_id" field.
+func SourceIDLTE(v uint64) predicate.MessageRecords {
+	return predicate.MessageRecords(sql.FieldLTE(FieldSourceID, v))
+}
+
+// SourceIDIsNil applies the IsNil predicate on the "source_id" field.
+func SourceIDIsNil() predicate.MessageRecords {
+	return predicate.MessageRecords(sql.FieldIsNull(FieldSourceID))
+}
+
+// SourceIDNotNil applies the NotNil predicate on the "source_id" field.
+func SourceIDNotNil() predicate.MessageRecords {
+	return predicate.MessageRecords(sql.FieldNotNull(FieldSourceID))
+}
+
+// SubSourceIDEQ applies the EQ predicate on the "sub_source_id" field.
+func SubSourceIDEQ(v uint64) predicate.MessageRecords {
+	return predicate.MessageRecords(sql.FieldEQ(FieldSubSourceID, v))
+}
+
+// SubSourceIDNEQ applies the NEQ predicate on the "sub_source_id" field.
+func SubSourceIDNEQ(v uint64) predicate.MessageRecords {
+	return predicate.MessageRecords(sql.FieldNEQ(FieldSubSourceID, v))
+}
+
+// SubSourceIDIn applies the In predicate on the "sub_source_id" field.
+func SubSourceIDIn(vs ...uint64) predicate.MessageRecords {
+	return predicate.MessageRecords(sql.FieldIn(FieldSubSourceID, vs...))
+}
+
+// SubSourceIDNotIn applies the NotIn predicate on the "sub_source_id" field.
+func SubSourceIDNotIn(vs ...uint64) predicate.MessageRecords {
+	return predicate.MessageRecords(sql.FieldNotIn(FieldSubSourceID, vs...))
+}
+
+// SubSourceIDGT applies the GT predicate on the "sub_source_id" field.
+func SubSourceIDGT(v uint64) predicate.MessageRecords {
+	return predicate.MessageRecords(sql.FieldGT(FieldSubSourceID, v))
+}
+
+// SubSourceIDGTE applies the GTE predicate on the "sub_source_id" field.
+func SubSourceIDGTE(v uint64) predicate.MessageRecords {
+	return predicate.MessageRecords(sql.FieldGTE(FieldSubSourceID, v))
+}
+
+// SubSourceIDLT applies the LT predicate on the "sub_source_id" field.
+func SubSourceIDLT(v uint64) predicate.MessageRecords {
+	return predicate.MessageRecords(sql.FieldLT(FieldSubSourceID, v))
+}
+
+// SubSourceIDLTE applies the LTE predicate on the "sub_source_id" field.
+func SubSourceIDLTE(v uint64) predicate.MessageRecords {
+	return predicate.MessageRecords(sql.FieldLTE(FieldSubSourceID, v))
+}
+
+// SubSourceIDIsNil applies the IsNil predicate on the "sub_source_id" field.
+func SubSourceIDIsNil() predicate.MessageRecords {
+	return predicate.MessageRecords(sql.FieldIsNull(FieldSubSourceID))
+}
+
+// SubSourceIDNotNil applies the NotNil predicate on the "sub_source_id" field.
+func SubSourceIDNotNil() predicate.MessageRecords {
+	return predicate.MessageRecords(sql.FieldNotNull(FieldSubSourceID))
+}
+
+// And groups predicates with the AND operator between them.
+func And(predicates ...predicate.MessageRecords) predicate.MessageRecords {
+	return predicate.MessageRecords(sql.AndPredicates(predicates...))
+}
+
+// Or groups predicates with the OR operator between them.
+func Or(predicates ...predicate.MessageRecords) predicate.MessageRecords {
+	return predicate.MessageRecords(sql.OrPredicates(predicates...))
+}
+
+// Not applies the not operator on the given predicate.
+func Not(p predicate.MessageRecords) predicate.MessageRecords {
+	return predicate.MessageRecords(sql.NotPredicates(p))
+}

+ 504 - 0
ent/messagerecords_create.go

@@ -0,0 +1,504 @@
+// Code generated by ent, DO NOT EDIT.
+
+package ent
+
+import (
+	"context"
+	"errors"
+	"fmt"
+	"time"
+
+	"entgo.io/ent/dialect/sql/sqlgraph"
+	"entgo.io/ent/schema/field"
+	"github.com/suyuan32/simple-admin-job/ent/messagerecords"
+)
+
+// MessageRecordsCreate is the builder for creating a MessageRecords entity.
+type MessageRecordsCreate struct {
+	config
+	mutation *MessageRecordsMutation
+	hooks    []Hook
+}
+
+// SetCreatedAt sets the "created_at" field.
+func (mrc *MessageRecordsCreate) SetCreatedAt(t time.Time) *MessageRecordsCreate {
+	mrc.mutation.SetCreatedAt(t)
+	return mrc
+}
+
+// SetNillableCreatedAt sets the "created_at" field if the given value is not nil.
+func (mrc *MessageRecordsCreate) SetNillableCreatedAt(t *time.Time) *MessageRecordsCreate {
+	if t != nil {
+		mrc.SetCreatedAt(*t)
+	}
+	return mrc
+}
+
+// SetUpdatedAt sets the "updated_at" field.
+func (mrc *MessageRecordsCreate) SetUpdatedAt(t time.Time) *MessageRecordsCreate {
+	mrc.mutation.SetUpdatedAt(t)
+	return mrc
+}
+
+// SetNillableUpdatedAt sets the "updated_at" field if the given value is not nil.
+func (mrc *MessageRecordsCreate) SetNillableUpdatedAt(t *time.Time) *MessageRecordsCreate {
+	if t != nil {
+		mrc.SetUpdatedAt(*t)
+	}
+	return mrc
+}
+
+// SetStatus sets the "status" field.
+func (mrc *MessageRecordsCreate) SetStatus(u uint8) *MessageRecordsCreate {
+	mrc.mutation.SetStatus(u)
+	return mrc
+}
+
+// SetNillableStatus sets the "status" field if the given value is not nil.
+func (mrc *MessageRecordsCreate) SetNillableStatus(u *uint8) *MessageRecordsCreate {
+	if u != nil {
+		mrc.SetStatus(*u)
+	}
+	return mrc
+}
+
+// SetBotWxid sets the "bot_wxid" field.
+func (mrc *MessageRecordsCreate) SetBotWxid(s string) *MessageRecordsCreate {
+	mrc.mutation.SetBotWxid(s)
+	return mrc
+}
+
+// SetContactID sets the "contact_id" field.
+func (mrc *MessageRecordsCreate) SetContactID(u uint64) *MessageRecordsCreate {
+	mrc.mutation.SetContactID(u)
+	return mrc
+}
+
+// SetNillableContactID sets the "contact_id" field if the given value is not nil.
+func (mrc *MessageRecordsCreate) SetNillableContactID(u *uint64) *MessageRecordsCreate {
+	if u != nil {
+		mrc.SetContactID(*u)
+	}
+	return mrc
+}
+
+// SetContactType sets the "contact_type" field.
+func (mrc *MessageRecordsCreate) SetContactType(i int) *MessageRecordsCreate {
+	mrc.mutation.SetContactType(i)
+	return mrc
+}
+
+// SetNillableContactType sets the "contact_type" field if the given value is not nil.
+func (mrc *MessageRecordsCreate) SetNillableContactType(i *int) *MessageRecordsCreate {
+	if i != nil {
+		mrc.SetContactType(*i)
+	}
+	return mrc
+}
+
+// SetContactWxid sets the "contact_wxid" field.
+func (mrc *MessageRecordsCreate) SetContactWxid(s string) *MessageRecordsCreate {
+	mrc.mutation.SetContactWxid(s)
+	return mrc
+}
+
+// SetNillableContactWxid sets the "contact_wxid" field if the given value is not nil.
+func (mrc *MessageRecordsCreate) SetNillableContactWxid(s *string) *MessageRecordsCreate {
+	if s != nil {
+		mrc.SetContactWxid(*s)
+	}
+	return mrc
+}
+
+// SetContentType sets the "content_type" field.
+func (mrc *MessageRecordsCreate) SetContentType(i int) *MessageRecordsCreate {
+	mrc.mutation.SetContentType(i)
+	return mrc
+}
+
+// SetNillableContentType sets the "content_type" field if the given value is not nil.
+func (mrc *MessageRecordsCreate) SetNillableContentType(i *int) *MessageRecordsCreate {
+	if i != nil {
+		mrc.SetContentType(*i)
+	}
+	return mrc
+}
+
+// SetContent sets the "content" field.
+func (mrc *MessageRecordsCreate) SetContent(s string) *MessageRecordsCreate {
+	mrc.mutation.SetContent(s)
+	return mrc
+}
+
+// SetNillableContent sets the "content" field if the given value is not nil.
+func (mrc *MessageRecordsCreate) SetNillableContent(s *string) *MessageRecordsCreate {
+	if s != nil {
+		mrc.SetContent(*s)
+	}
+	return mrc
+}
+
+// SetErrorDetail sets the "error_detail" field.
+func (mrc *MessageRecordsCreate) SetErrorDetail(s string) *MessageRecordsCreate {
+	mrc.mutation.SetErrorDetail(s)
+	return mrc
+}
+
+// SetNillableErrorDetail sets the "error_detail" field if the given value is not nil.
+func (mrc *MessageRecordsCreate) SetNillableErrorDetail(s *string) *MessageRecordsCreate {
+	if s != nil {
+		mrc.SetErrorDetail(*s)
+	}
+	return mrc
+}
+
+// SetSendTime sets the "send_time" field.
+func (mrc *MessageRecordsCreate) SetSendTime(t time.Time) *MessageRecordsCreate {
+	mrc.mutation.SetSendTime(t)
+	return mrc
+}
+
+// SetNillableSendTime sets the "send_time" field if the given value is not nil.
+func (mrc *MessageRecordsCreate) SetNillableSendTime(t *time.Time) *MessageRecordsCreate {
+	if t != nil {
+		mrc.SetSendTime(*t)
+	}
+	return mrc
+}
+
+// SetSourceType sets the "source_type" field.
+func (mrc *MessageRecordsCreate) SetSourceType(i int) *MessageRecordsCreate {
+	mrc.mutation.SetSourceType(i)
+	return mrc
+}
+
+// SetNillableSourceType sets the "source_type" field if the given value is not nil.
+func (mrc *MessageRecordsCreate) SetNillableSourceType(i *int) *MessageRecordsCreate {
+	if i != nil {
+		mrc.SetSourceType(*i)
+	}
+	return mrc
+}
+
+// SetSourceID sets the "source_id" field.
+func (mrc *MessageRecordsCreate) SetSourceID(u uint64) *MessageRecordsCreate {
+	mrc.mutation.SetSourceID(u)
+	return mrc
+}
+
+// SetNillableSourceID sets the "source_id" field if the given value is not nil.
+func (mrc *MessageRecordsCreate) SetNillableSourceID(u *uint64) *MessageRecordsCreate {
+	if u != nil {
+		mrc.SetSourceID(*u)
+	}
+	return mrc
+}
+
+// SetSubSourceID sets the "sub_source_id" field.
+func (mrc *MessageRecordsCreate) SetSubSourceID(u uint64) *MessageRecordsCreate {
+	mrc.mutation.SetSubSourceID(u)
+	return mrc
+}
+
+// SetNillableSubSourceID sets the "sub_source_id" field if the given value is not nil.
+func (mrc *MessageRecordsCreate) SetNillableSubSourceID(u *uint64) *MessageRecordsCreate {
+	if u != nil {
+		mrc.SetSubSourceID(*u)
+	}
+	return mrc
+}
+
+// SetID sets the "id" field.
+func (mrc *MessageRecordsCreate) SetID(u uint64) *MessageRecordsCreate {
+	mrc.mutation.SetID(u)
+	return mrc
+}
+
+// Mutation returns the MessageRecordsMutation object of the builder.
+func (mrc *MessageRecordsCreate) Mutation() *MessageRecordsMutation {
+	return mrc.mutation
+}
+
+// Save creates the MessageRecords in the database.
+func (mrc *MessageRecordsCreate) Save(ctx context.Context) (*MessageRecords, error) {
+	mrc.defaults()
+	return withHooks(ctx, mrc.sqlSave, mrc.mutation, mrc.hooks)
+}
+
+// SaveX calls Save and panics if Save returns an error.
+func (mrc *MessageRecordsCreate) SaveX(ctx context.Context) *MessageRecords {
+	v, err := mrc.Save(ctx)
+	if err != nil {
+		panic(err)
+	}
+	return v
+}
+
+// Exec executes the query.
+func (mrc *MessageRecordsCreate) Exec(ctx context.Context) error {
+	_, err := mrc.Save(ctx)
+	return err
+}
+
+// ExecX is like Exec, but panics if an error occurs.
+func (mrc *MessageRecordsCreate) ExecX(ctx context.Context) {
+	if err := mrc.Exec(ctx); err != nil {
+		panic(err)
+	}
+}
+
+// defaults sets the default values of the builder before save.
+func (mrc *MessageRecordsCreate) defaults() {
+	if _, ok := mrc.mutation.CreatedAt(); !ok {
+		v := messagerecords.DefaultCreatedAt()
+		mrc.mutation.SetCreatedAt(v)
+	}
+	if _, ok := mrc.mutation.UpdatedAt(); !ok {
+		v := messagerecords.DefaultUpdatedAt()
+		mrc.mutation.SetUpdatedAt(v)
+	}
+	if _, ok := mrc.mutation.Status(); !ok {
+		v := messagerecords.DefaultStatus
+		mrc.mutation.SetStatus(v)
+	}
+	if _, ok := mrc.mutation.ContactType(); !ok {
+		v := messagerecords.DefaultContactType
+		mrc.mutation.SetContactType(v)
+	}
+	if _, ok := mrc.mutation.ContactWxid(); !ok {
+		v := messagerecords.DefaultContactWxid
+		mrc.mutation.SetContactWxid(v)
+	}
+	if _, ok := mrc.mutation.ContentType(); !ok {
+		v := messagerecords.DefaultContentType
+		mrc.mutation.SetContentType(v)
+	}
+	if _, ok := mrc.mutation.Content(); !ok {
+		v := messagerecords.DefaultContent
+		mrc.mutation.SetContent(v)
+	}
+	if _, ok := mrc.mutation.ErrorDetail(); !ok {
+		v := messagerecords.DefaultErrorDetail
+		mrc.mutation.SetErrorDetail(v)
+	}
+	if _, ok := mrc.mutation.SourceType(); !ok {
+		v := messagerecords.DefaultSourceType
+		mrc.mutation.SetSourceType(v)
+	}
+	if _, ok := mrc.mutation.SourceID(); !ok {
+		v := messagerecords.DefaultSourceID
+		mrc.mutation.SetSourceID(v)
+	}
+	if _, ok := mrc.mutation.SubSourceID(); !ok {
+		v := messagerecords.DefaultSubSourceID
+		mrc.mutation.SetSubSourceID(v)
+	}
+}
+
+// check runs all checks and user-defined validators on the builder.
+func (mrc *MessageRecordsCreate) check() error {
+	if _, ok := mrc.mutation.CreatedAt(); !ok {
+		return &ValidationError{Name: "created_at", err: errors.New(`ent: missing required field "MessageRecords.created_at"`)}
+	}
+	if _, ok := mrc.mutation.UpdatedAt(); !ok {
+		return &ValidationError{Name: "updated_at", err: errors.New(`ent: missing required field "MessageRecords.updated_at"`)}
+	}
+	if _, ok := mrc.mutation.BotWxid(); !ok {
+		return &ValidationError{Name: "bot_wxid", err: errors.New(`ent: missing required field "MessageRecords.bot_wxid"`)}
+	}
+	if _, ok := mrc.mutation.ContactType(); !ok {
+		return &ValidationError{Name: "contact_type", err: errors.New(`ent: missing required field "MessageRecords.contact_type"`)}
+	}
+	if _, ok := mrc.mutation.ContactWxid(); !ok {
+		return &ValidationError{Name: "contact_wxid", err: errors.New(`ent: missing required field "MessageRecords.contact_wxid"`)}
+	}
+	if _, ok := mrc.mutation.ContentType(); !ok {
+		return &ValidationError{Name: "content_type", err: errors.New(`ent: missing required field "MessageRecords.content_type"`)}
+	}
+	if _, ok := mrc.mutation.Content(); !ok {
+		return &ValidationError{Name: "content", err: errors.New(`ent: missing required field "MessageRecords.content"`)}
+	}
+	if _, ok := mrc.mutation.ErrorDetail(); !ok {
+		return &ValidationError{Name: "error_detail", err: errors.New(`ent: missing required field "MessageRecords.error_detail"`)}
+	}
+	if _, ok := mrc.mutation.SourceType(); !ok {
+		return &ValidationError{Name: "source_type", err: errors.New(`ent: missing required field "MessageRecords.source_type"`)}
+	}
+	return nil
+}
+
+func (mrc *MessageRecordsCreate) sqlSave(ctx context.Context) (*MessageRecords, error) {
+	if err := mrc.check(); err != nil {
+		return nil, err
+	}
+	_node, _spec := mrc.createSpec()
+	if err := sqlgraph.CreateNode(ctx, mrc.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)
+	}
+	mrc.mutation.id = &_node.ID
+	mrc.mutation.done = true
+	return _node, nil
+}
+
+func (mrc *MessageRecordsCreate) createSpec() (*MessageRecords, *sqlgraph.CreateSpec) {
+	var (
+		_node = &MessageRecords{config: mrc.config}
+		_spec = sqlgraph.NewCreateSpec(messagerecords.Table, sqlgraph.NewFieldSpec(messagerecords.FieldID, field.TypeUint64))
+	)
+	if id, ok := mrc.mutation.ID(); ok {
+		_node.ID = id
+		_spec.ID.Value = id
+	}
+	if value, ok := mrc.mutation.CreatedAt(); ok {
+		_spec.SetField(messagerecords.FieldCreatedAt, field.TypeTime, value)
+		_node.CreatedAt = value
+	}
+	if value, ok := mrc.mutation.UpdatedAt(); ok {
+		_spec.SetField(messagerecords.FieldUpdatedAt, field.TypeTime, value)
+		_node.UpdatedAt = value
+	}
+	if value, ok := mrc.mutation.Status(); ok {
+		_spec.SetField(messagerecords.FieldStatus, field.TypeUint8, value)
+		_node.Status = value
+	}
+	if value, ok := mrc.mutation.BotWxid(); ok {
+		_spec.SetField(messagerecords.FieldBotWxid, field.TypeString, value)
+		_node.BotWxid = value
+	}
+	if value, ok := mrc.mutation.ContactID(); ok {
+		_spec.SetField(messagerecords.FieldContactID, field.TypeUint64, value)
+		_node.ContactID = value
+	}
+	if value, ok := mrc.mutation.ContactType(); ok {
+		_spec.SetField(messagerecords.FieldContactType, field.TypeInt, value)
+		_node.ContactType = value
+	}
+	if value, ok := mrc.mutation.ContactWxid(); ok {
+		_spec.SetField(messagerecords.FieldContactWxid, field.TypeString, value)
+		_node.ContactWxid = value
+	}
+	if value, ok := mrc.mutation.ContentType(); ok {
+		_spec.SetField(messagerecords.FieldContentType, field.TypeInt, value)
+		_node.ContentType = value
+	}
+	if value, ok := mrc.mutation.Content(); ok {
+		_spec.SetField(messagerecords.FieldContent, field.TypeString, value)
+		_node.Content = value
+	}
+	if value, ok := mrc.mutation.ErrorDetail(); ok {
+		_spec.SetField(messagerecords.FieldErrorDetail, field.TypeString, value)
+		_node.ErrorDetail = value
+	}
+	if value, ok := mrc.mutation.SendTime(); ok {
+		_spec.SetField(messagerecords.FieldSendTime, field.TypeTime, value)
+		_node.SendTime = value
+	}
+	if value, ok := mrc.mutation.SourceType(); ok {
+		_spec.SetField(messagerecords.FieldSourceType, field.TypeInt, value)
+		_node.SourceType = value
+	}
+	if value, ok := mrc.mutation.SourceID(); ok {
+		_spec.SetField(messagerecords.FieldSourceID, field.TypeUint64, value)
+		_node.SourceID = value
+	}
+	if value, ok := mrc.mutation.SubSourceID(); ok {
+		_spec.SetField(messagerecords.FieldSubSourceID, field.TypeUint64, value)
+		_node.SubSourceID = value
+	}
+	return _node, _spec
+}
+
+// MessageRecordsCreateBulk is the builder for creating many MessageRecords entities in bulk.
+type MessageRecordsCreateBulk struct {
+	config
+	err      error
+	builders []*MessageRecordsCreate
+}
+
+// Save creates the MessageRecords entities in the database.
+func (mrcb *MessageRecordsCreateBulk) Save(ctx context.Context) ([]*MessageRecords, error) {
+	if mrcb.err != nil {
+		return nil, mrcb.err
+	}
+	specs := make([]*sqlgraph.CreateSpec, len(mrcb.builders))
+	nodes := make([]*MessageRecords, len(mrcb.builders))
+	mutators := make([]Mutator, len(mrcb.builders))
+	for i := range mrcb.builders {
+		func(i int, root context.Context) {
+			builder := mrcb.builders[i]
+			builder.defaults()
+			var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) {
+				mutation, ok := m.(*MessageRecordsMutation)
+				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, mrcb.builders[i+1].mutation)
+				} else {
+					spec := &sqlgraph.BatchCreateSpec{Nodes: specs}
+					// Invoke the actual operation on the latest mutation in the chain.
+					if err = sqlgraph.BatchCreate(ctx, mrcb.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, mrcb.builders[0].mutation); err != nil {
+			return nil, err
+		}
+	}
+	return nodes, nil
+}
+
+// SaveX is like Save, but panics if an error occurs.
+func (mrcb *MessageRecordsCreateBulk) SaveX(ctx context.Context) []*MessageRecords {
+	v, err := mrcb.Save(ctx)
+	if err != nil {
+		panic(err)
+	}
+	return v
+}
+
+// Exec executes the query.
+func (mrcb *MessageRecordsCreateBulk) Exec(ctx context.Context) error {
+	_, err := mrcb.Save(ctx)
+	return err
+}
+
+// ExecX is like Exec, but panics if an error occurs.
+func (mrcb *MessageRecordsCreateBulk) ExecX(ctx context.Context) {
+	if err := mrcb.Exec(ctx); err != nil {
+		panic(err)
+	}
+}

+ 88 - 0
ent/messagerecords_delete.go

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

+ 526 - 0
ent/messagerecords_query.go

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

+ 850 - 0
ent/messagerecords_update.go

@@ -0,0 +1,850 @@
+// Code generated by ent, DO NOT EDIT.
+
+package ent
+
+import (
+	"context"
+	"errors"
+	"fmt"
+	"time"
+
+	"entgo.io/ent/dialect/sql"
+	"entgo.io/ent/dialect/sql/sqlgraph"
+	"entgo.io/ent/schema/field"
+	"github.com/suyuan32/simple-admin-job/ent/messagerecords"
+	"github.com/suyuan32/simple-admin-job/ent/predicate"
+)
+
+// MessageRecordsUpdate is the builder for updating MessageRecords entities.
+type MessageRecordsUpdate struct {
+	config
+	hooks    []Hook
+	mutation *MessageRecordsMutation
+}
+
+// Where appends a list predicates to the MessageRecordsUpdate builder.
+func (mru *MessageRecordsUpdate) Where(ps ...predicate.MessageRecords) *MessageRecordsUpdate {
+	mru.mutation.Where(ps...)
+	return mru
+}
+
+// SetUpdatedAt sets the "updated_at" field.
+func (mru *MessageRecordsUpdate) SetUpdatedAt(t time.Time) *MessageRecordsUpdate {
+	mru.mutation.SetUpdatedAt(t)
+	return mru
+}
+
+// SetStatus sets the "status" field.
+func (mru *MessageRecordsUpdate) SetStatus(u uint8) *MessageRecordsUpdate {
+	mru.mutation.ResetStatus()
+	mru.mutation.SetStatus(u)
+	return mru
+}
+
+// SetNillableStatus sets the "status" field if the given value is not nil.
+func (mru *MessageRecordsUpdate) SetNillableStatus(u *uint8) *MessageRecordsUpdate {
+	if u != nil {
+		mru.SetStatus(*u)
+	}
+	return mru
+}
+
+// AddStatus adds u to the "status" field.
+func (mru *MessageRecordsUpdate) AddStatus(u int8) *MessageRecordsUpdate {
+	mru.mutation.AddStatus(u)
+	return mru
+}
+
+// ClearStatus clears the value of the "status" field.
+func (mru *MessageRecordsUpdate) ClearStatus() *MessageRecordsUpdate {
+	mru.mutation.ClearStatus()
+	return mru
+}
+
+// SetBotWxid sets the "bot_wxid" field.
+func (mru *MessageRecordsUpdate) SetBotWxid(s string) *MessageRecordsUpdate {
+	mru.mutation.SetBotWxid(s)
+	return mru
+}
+
+// SetNillableBotWxid sets the "bot_wxid" field if the given value is not nil.
+func (mru *MessageRecordsUpdate) SetNillableBotWxid(s *string) *MessageRecordsUpdate {
+	if s != nil {
+		mru.SetBotWxid(*s)
+	}
+	return mru
+}
+
+// SetContactID sets the "contact_id" field.
+func (mru *MessageRecordsUpdate) SetContactID(u uint64) *MessageRecordsUpdate {
+	mru.mutation.ResetContactID()
+	mru.mutation.SetContactID(u)
+	return mru
+}
+
+// SetNillableContactID sets the "contact_id" field if the given value is not nil.
+func (mru *MessageRecordsUpdate) SetNillableContactID(u *uint64) *MessageRecordsUpdate {
+	if u != nil {
+		mru.SetContactID(*u)
+	}
+	return mru
+}
+
+// AddContactID adds u to the "contact_id" field.
+func (mru *MessageRecordsUpdate) AddContactID(u int64) *MessageRecordsUpdate {
+	mru.mutation.AddContactID(u)
+	return mru
+}
+
+// ClearContactID clears the value of the "contact_id" field.
+func (mru *MessageRecordsUpdate) ClearContactID() *MessageRecordsUpdate {
+	mru.mutation.ClearContactID()
+	return mru
+}
+
+// SetContactType sets the "contact_type" field.
+func (mru *MessageRecordsUpdate) SetContactType(i int) *MessageRecordsUpdate {
+	mru.mutation.ResetContactType()
+	mru.mutation.SetContactType(i)
+	return mru
+}
+
+// SetNillableContactType sets the "contact_type" field if the given value is not nil.
+func (mru *MessageRecordsUpdate) SetNillableContactType(i *int) *MessageRecordsUpdate {
+	if i != nil {
+		mru.SetContactType(*i)
+	}
+	return mru
+}
+
+// AddContactType adds i to the "contact_type" field.
+func (mru *MessageRecordsUpdate) AddContactType(i int) *MessageRecordsUpdate {
+	mru.mutation.AddContactType(i)
+	return mru
+}
+
+// SetContactWxid sets the "contact_wxid" field.
+func (mru *MessageRecordsUpdate) SetContactWxid(s string) *MessageRecordsUpdate {
+	mru.mutation.SetContactWxid(s)
+	return mru
+}
+
+// SetNillableContactWxid sets the "contact_wxid" field if the given value is not nil.
+func (mru *MessageRecordsUpdate) SetNillableContactWxid(s *string) *MessageRecordsUpdate {
+	if s != nil {
+		mru.SetContactWxid(*s)
+	}
+	return mru
+}
+
+// SetContentType sets the "content_type" field.
+func (mru *MessageRecordsUpdate) SetContentType(i int) *MessageRecordsUpdate {
+	mru.mutation.ResetContentType()
+	mru.mutation.SetContentType(i)
+	return mru
+}
+
+// SetNillableContentType sets the "content_type" field if the given value is not nil.
+func (mru *MessageRecordsUpdate) SetNillableContentType(i *int) *MessageRecordsUpdate {
+	if i != nil {
+		mru.SetContentType(*i)
+	}
+	return mru
+}
+
+// AddContentType adds i to the "content_type" field.
+func (mru *MessageRecordsUpdate) AddContentType(i int) *MessageRecordsUpdate {
+	mru.mutation.AddContentType(i)
+	return mru
+}
+
+// SetContent sets the "content" field.
+func (mru *MessageRecordsUpdate) SetContent(s string) *MessageRecordsUpdate {
+	mru.mutation.SetContent(s)
+	return mru
+}
+
+// SetNillableContent sets the "content" field if the given value is not nil.
+func (mru *MessageRecordsUpdate) SetNillableContent(s *string) *MessageRecordsUpdate {
+	if s != nil {
+		mru.SetContent(*s)
+	}
+	return mru
+}
+
+// SetErrorDetail sets the "error_detail" field.
+func (mru *MessageRecordsUpdate) SetErrorDetail(s string) *MessageRecordsUpdate {
+	mru.mutation.SetErrorDetail(s)
+	return mru
+}
+
+// SetNillableErrorDetail sets the "error_detail" field if the given value is not nil.
+func (mru *MessageRecordsUpdate) SetNillableErrorDetail(s *string) *MessageRecordsUpdate {
+	if s != nil {
+		mru.SetErrorDetail(*s)
+	}
+	return mru
+}
+
+// SetSendTime sets the "send_time" field.
+func (mru *MessageRecordsUpdate) SetSendTime(t time.Time) *MessageRecordsUpdate {
+	mru.mutation.SetSendTime(t)
+	return mru
+}
+
+// SetNillableSendTime sets the "send_time" field if the given value is not nil.
+func (mru *MessageRecordsUpdate) SetNillableSendTime(t *time.Time) *MessageRecordsUpdate {
+	if t != nil {
+		mru.SetSendTime(*t)
+	}
+	return mru
+}
+
+// ClearSendTime clears the value of the "send_time" field.
+func (mru *MessageRecordsUpdate) ClearSendTime() *MessageRecordsUpdate {
+	mru.mutation.ClearSendTime()
+	return mru
+}
+
+// SetSourceType sets the "source_type" field.
+func (mru *MessageRecordsUpdate) SetSourceType(i int) *MessageRecordsUpdate {
+	mru.mutation.ResetSourceType()
+	mru.mutation.SetSourceType(i)
+	return mru
+}
+
+// SetNillableSourceType sets the "source_type" field if the given value is not nil.
+func (mru *MessageRecordsUpdate) SetNillableSourceType(i *int) *MessageRecordsUpdate {
+	if i != nil {
+		mru.SetSourceType(*i)
+	}
+	return mru
+}
+
+// AddSourceType adds i to the "source_type" field.
+func (mru *MessageRecordsUpdate) AddSourceType(i int) *MessageRecordsUpdate {
+	mru.mutation.AddSourceType(i)
+	return mru
+}
+
+// SetSourceID sets the "source_id" field.
+func (mru *MessageRecordsUpdate) SetSourceID(u uint64) *MessageRecordsUpdate {
+	mru.mutation.ResetSourceID()
+	mru.mutation.SetSourceID(u)
+	return mru
+}
+
+// SetNillableSourceID sets the "source_id" field if the given value is not nil.
+func (mru *MessageRecordsUpdate) SetNillableSourceID(u *uint64) *MessageRecordsUpdate {
+	if u != nil {
+		mru.SetSourceID(*u)
+	}
+	return mru
+}
+
+// AddSourceID adds u to the "source_id" field.
+func (mru *MessageRecordsUpdate) AddSourceID(u int64) *MessageRecordsUpdate {
+	mru.mutation.AddSourceID(u)
+	return mru
+}
+
+// ClearSourceID clears the value of the "source_id" field.
+func (mru *MessageRecordsUpdate) ClearSourceID() *MessageRecordsUpdate {
+	mru.mutation.ClearSourceID()
+	return mru
+}
+
+// SetSubSourceID sets the "sub_source_id" field.
+func (mru *MessageRecordsUpdate) SetSubSourceID(u uint64) *MessageRecordsUpdate {
+	mru.mutation.ResetSubSourceID()
+	mru.mutation.SetSubSourceID(u)
+	return mru
+}
+
+// SetNillableSubSourceID sets the "sub_source_id" field if the given value is not nil.
+func (mru *MessageRecordsUpdate) SetNillableSubSourceID(u *uint64) *MessageRecordsUpdate {
+	if u != nil {
+		mru.SetSubSourceID(*u)
+	}
+	return mru
+}
+
+// AddSubSourceID adds u to the "sub_source_id" field.
+func (mru *MessageRecordsUpdate) AddSubSourceID(u int64) *MessageRecordsUpdate {
+	mru.mutation.AddSubSourceID(u)
+	return mru
+}
+
+// ClearSubSourceID clears the value of the "sub_source_id" field.
+func (mru *MessageRecordsUpdate) ClearSubSourceID() *MessageRecordsUpdate {
+	mru.mutation.ClearSubSourceID()
+	return mru
+}
+
+// Mutation returns the MessageRecordsMutation object of the builder.
+func (mru *MessageRecordsUpdate) Mutation() *MessageRecordsMutation {
+	return mru.mutation
+}
+
+// Save executes the query and returns the number of nodes affected by the update operation.
+func (mru *MessageRecordsUpdate) Save(ctx context.Context) (int, error) {
+	mru.defaults()
+	return withHooks(ctx, mru.sqlSave, mru.mutation, mru.hooks)
+}
+
+// SaveX is like Save, but panics if an error occurs.
+func (mru *MessageRecordsUpdate) SaveX(ctx context.Context) int {
+	affected, err := mru.Save(ctx)
+	if err != nil {
+		panic(err)
+	}
+	return affected
+}
+
+// Exec executes the query.
+func (mru *MessageRecordsUpdate) Exec(ctx context.Context) error {
+	_, err := mru.Save(ctx)
+	return err
+}
+
+// ExecX is like Exec, but panics if an error occurs.
+func (mru *MessageRecordsUpdate) ExecX(ctx context.Context) {
+	if err := mru.Exec(ctx); err != nil {
+		panic(err)
+	}
+}
+
+// defaults sets the default values of the builder before save.
+func (mru *MessageRecordsUpdate) defaults() {
+	if _, ok := mru.mutation.UpdatedAt(); !ok {
+		v := messagerecords.UpdateDefaultUpdatedAt()
+		mru.mutation.SetUpdatedAt(v)
+	}
+}
+
+func (mru *MessageRecordsUpdate) sqlSave(ctx context.Context) (n int, err error) {
+	_spec := sqlgraph.NewUpdateSpec(messagerecords.Table, messagerecords.Columns, sqlgraph.NewFieldSpec(messagerecords.FieldID, field.TypeUint64))
+	if ps := mru.mutation.predicates; len(ps) > 0 {
+		_spec.Predicate = func(selector *sql.Selector) {
+			for i := range ps {
+				ps[i](selector)
+			}
+		}
+	}
+	if value, ok := mru.mutation.UpdatedAt(); ok {
+		_spec.SetField(messagerecords.FieldUpdatedAt, field.TypeTime, value)
+	}
+	if value, ok := mru.mutation.Status(); ok {
+		_spec.SetField(messagerecords.FieldStatus, field.TypeUint8, value)
+	}
+	if value, ok := mru.mutation.AddedStatus(); ok {
+		_spec.AddField(messagerecords.FieldStatus, field.TypeUint8, value)
+	}
+	if mru.mutation.StatusCleared() {
+		_spec.ClearField(messagerecords.FieldStatus, field.TypeUint8)
+	}
+	if value, ok := mru.mutation.BotWxid(); ok {
+		_spec.SetField(messagerecords.FieldBotWxid, field.TypeString, value)
+	}
+	if value, ok := mru.mutation.ContactID(); ok {
+		_spec.SetField(messagerecords.FieldContactID, field.TypeUint64, value)
+	}
+	if value, ok := mru.mutation.AddedContactID(); ok {
+		_spec.AddField(messagerecords.FieldContactID, field.TypeUint64, value)
+	}
+	if mru.mutation.ContactIDCleared() {
+		_spec.ClearField(messagerecords.FieldContactID, field.TypeUint64)
+	}
+	if value, ok := mru.mutation.ContactType(); ok {
+		_spec.SetField(messagerecords.FieldContactType, field.TypeInt, value)
+	}
+	if value, ok := mru.mutation.AddedContactType(); ok {
+		_spec.AddField(messagerecords.FieldContactType, field.TypeInt, value)
+	}
+	if value, ok := mru.mutation.ContactWxid(); ok {
+		_spec.SetField(messagerecords.FieldContactWxid, field.TypeString, value)
+	}
+	if value, ok := mru.mutation.ContentType(); ok {
+		_spec.SetField(messagerecords.FieldContentType, field.TypeInt, value)
+	}
+	if value, ok := mru.mutation.AddedContentType(); ok {
+		_spec.AddField(messagerecords.FieldContentType, field.TypeInt, value)
+	}
+	if value, ok := mru.mutation.Content(); ok {
+		_spec.SetField(messagerecords.FieldContent, field.TypeString, value)
+	}
+	if value, ok := mru.mutation.ErrorDetail(); ok {
+		_spec.SetField(messagerecords.FieldErrorDetail, field.TypeString, value)
+	}
+	if value, ok := mru.mutation.SendTime(); ok {
+		_spec.SetField(messagerecords.FieldSendTime, field.TypeTime, value)
+	}
+	if mru.mutation.SendTimeCleared() {
+		_spec.ClearField(messagerecords.FieldSendTime, field.TypeTime)
+	}
+	if value, ok := mru.mutation.SourceType(); ok {
+		_spec.SetField(messagerecords.FieldSourceType, field.TypeInt, value)
+	}
+	if value, ok := mru.mutation.AddedSourceType(); ok {
+		_spec.AddField(messagerecords.FieldSourceType, field.TypeInt, value)
+	}
+	if value, ok := mru.mutation.SourceID(); ok {
+		_spec.SetField(messagerecords.FieldSourceID, field.TypeUint64, value)
+	}
+	if value, ok := mru.mutation.AddedSourceID(); ok {
+		_spec.AddField(messagerecords.FieldSourceID, field.TypeUint64, value)
+	}
+	if mru.mutation.SourceIDCleared() {
+		_spec.ClearField(messagerecords.FieldSourceID, field.TypeUint64)
+	}
+	if value, ok := mru.mutation.SubSourceID(); ok {
+		_spec.SetField(messagerecords.FieldSubSourceID, field.TypeUint64, value)
+	}
+	if value, ok := mru.mutation.AddedSubSourceID(); ok {
+		_spec.AddField(messagerecords.FieldSubSourceID, field.TypeUint64, value)
+	}
+	if mru.mutation.SubSourceIDCleared() {
+		_spec.ClearField(messagerecords.FieldSubSourceID, field.TypeUint64)
+	}
+	if n, err = sqlgraph.UpdateNodes(ctx, mru.driver, _spec); err != nil {
+		if _, ok := err.(*sqlgraph.NotFoundError); ok {
+			err = &NotFoundError{messagerecords.Label}
+		} else if sqlgraph.IsConstraintError(err) {
+			err = &ConstraintError{msg: err.Error(), wrap: err}
+		}
+		return 0, err
+	}
+	mru.mutation.done = true
+	return n, nil
+}
+
+// MessageRecordsUpdateOne is the builder for updating a single MessageRecords entity.
+type MessageRecordsUpdateOne struct {
+	config
+	fields   []string
+	hooks    []Hook
+	mutation *MessageRecordsMutation
+}
+
+// SetUpdatedAt sets the "updated_at" field.
+func (mruo *MessageRecordsUpdateOne) SetUpdatedAt(t time.Time) *MessageRecordsUpdateOne {
+	mruo.mutation.SetUpdatedAt(t)
+	return mruo
+}
+
+// SetStatus sets the "status" field.
+func (mruo *MessageRecordsUpdateOne) SetStatus(u uint8) *MessageRecordsUpdateOne {
+	mruo.mutation.ResetStatus()
+	mruo.mutation.SetStatus(u)
+	return mruo
+}
+
+// SetNillableStatus sets the "status" field if the given value is not nil.
+func (mruo *MessageRecordsUpdateOne) SetNillableStatus(u *uint8) *MessageRecordsUpdateOne {
+	if u != nil {
+		mruo.SetStatus(*u)
+	}
+	return mruo
+}
+
+// AddStatus adds u to the "status" field.
+func (mruo *MessageRecordsUpdateOne) AddStatus(u int8) *MessageRecordsUpdateOne {
+	mruo.mutation.AddStatus(u)
+	return mruo
+}
+
+// ClearStatus clears the value of the "status" field.
+func (mruo *MessageRecordsUpdateOne) ClearStatus() *MessageRecordsUpdateOne {
+	mruo.mutation.ClearStatus()
+	return mruo
+}
+
+// SetBotWxid sets the "bot_wxid" field.
+func (mruo *MessageRecordsUpdateOne) SetBotWxid(s string) *MessageRecordsUpdateOne {
+	mruo.mutation.SetBotWxid(s)
+	return mruo
+}
+
+// SetNillableBotWxid sets the "bot_wxid" field if the given value is not nil.
+func (mruo *MessageRecordsUpdateOne) SetNillableBotWxid(s *string) *MessageRecordsUpdateOne {
+	if s != nil {
+		mruo.SetBotWxid(*s)
+	}
+	return mruo
+}
+
+// SetContactID sets the "contact_id" field.
+func (mruo *MessageRecordsUpdateOne) SetContactID(u uint64) *MessageRecordsUpdateOne {
+	mruo.mutation.ResetContactID()
+	mruo.mutation.SetContactID(u)
+	return mruo
+}
+
+// SetNillableContactID sets the "contact_id" field if the given value is not nil.
+func (mruo *MessageRecordsUpdateOne) SetNillableContactID(u *uint64) *MessageRecordsUpdateOne {
+	if u != nil {
+		mruo.SetContactID(*u)
+	}
+	return mruo
+}
+
+// AddContactID adds u to the "contact_id" field.
+func (mruo *MessageRecordsUpdateOne) AddContactID(u int64) *MessageRecordsUpdateOne {
+	mruo.mutation.AddContactID(u)
+	return mruo
+}
+
+// ClearContactID clears the value of the "contact_id" field.
+func (mruo *MessageRecordsUpdateOne) ClearContactID() *MessageRecordsUpdateOne {
+	mruo.mutation.ClearContactID()
+	return mruo
+}
+
+// SetContactType sets the "contact_type" field.
+func (mruo *MessageRecordsUpdateOne) SetContactType(i int) *MessageRecordsUpdateOne {
+	mruo.mutation.ResetContactType()
+	mruo.mutation.SetContactType(i)
+	return mruo
+}
+
+// SetNillableContactType sets the "contact_type" field if the given value is not nil.
+func (mruo *MessageRecordsUpdateOne) SetNillableContactType(i *int) *MessageRecordsUpdateOne {
+	if i != nil {
+		mruo.SetContactType(*i)
+	}
+	return mruo
+}
+
+// AddContactType adds i to the "contact_type" field.
+func (mruo *MessageRecordsUpdateOne) AddContactType(i int) *MessageRecordsUpdateOne {
+	mruo.mutation.AddContactType(i)
+	return mruo
+}
+
+// SetContactWxid sets the "contact_wxid" field.
+func (mruo *MessageRecordsUpdateOne) SetContactWxid(s string) *MessageRecordsUpdateOne {
+	mruo.mutation.SetContactWxid(s)
+	return mruo
+}
+
+// SetNillableContactWxid sets the "contact_wxid" field if the given value is not nil.
+func (mruo *MessageRecordsUpdateOne) SetNillableContactWxid(s *string) *MessageRecordsUpdateOne {
+	if s != nil {
+		mruo.SetContactWxid(*s)
+	}
+	return mruo
+}
+
+// SetContentType sets the "content_type" field.
+func (mruo *MessageRecordsUpdateOne) SetContentType(i int) *MessageRecordsUpdateOne {
+	mruo.mutation.ResetContentType()
+	mruo.mutation.SetContentType(i)
+	return mruo
+}
+
+// SetNillableContentType sets the "content_type" field if the given value is not nil.
+func (mruo *MessageRecordsUpdateOne) SetNillableContentType(i *int) *MessageRecordsUpdateOne {
+	if i != nil {
+		mruo.SetContentType(*i)
+	}
+	return mruo
+}
+
+// AddContentType adds i to the "content_type" field.
+func (mruo *MessageRecordsUpdateOne) AddContentType(i int) *MessageRecordsUpdateOne {
+	mruo.mutation.AddContentType(i)
+	return mruo
+}
+
+// SetContent sets the "content" field.
+func (mruo *MessageRecordsUpdateOne) SetContent(s string) *MessageRecordsUpdateOne {
+	mruo.mutation.SetContent(s)
+	return mruo
+}
+
+// SetNillableContent sets the "content" field if the given value is not nil.
+func (mruo *MessageRecordsUpdateOne) SetNillableContent(s *string) *MessageRecordsUpdateOne {
+	if s != nil {
+		mruo.SetContent(*s)
+	}
+	return mruo
+}
+
+// SetErrorDetail sets the "error_detail" field.
+func (mruo *MessageRecordsUpdateOne) SetErrorDetail(s string) *MessageRecordsUpdateOne {
+	mruo.mutation.SetErrorDetail(s)
+	return mruo
+}
+
+// SetNillableErrorDetail sets the "error_detail" field if the given value is not nil.
+func (mruo *MessageRecordsUpdateOne) SetNillableErrorDetail(s *string) *MessageRecordsUpdateOne {
+	if s != nil {
+		mruo.SetErrorDetail(*s)
+	}
+	return mruo
+}
+
+// SetSendTime sets the "send_time" field.
+func (mruo *MessageRecordsUpdateOne) SetSendTime(t time.Time) *MessageRecordsUpdateOne {
+	mruo.mutation.SetSendTime(t)
+	return mruo
+}
+
+// SetNillableSendTime sets the "send_time" field if the given value is not nil.
+func (mruo *MessageRecordsUpdateOne) SetNillableSendTime(t *time.Time) *MessageRecordsUpdateOne {
+	if t != nil {
+		mruo.SetSendTime(*t)
+	}
+	return mruo
+}
+
+// ClearSendTime clears the value of the "send_time" field.
+func (mruo *MessageRecordsUpdateOne) ClearSendTime() *MessageRecordsUpdateOne {
+	mruo.mutation.ClearSendTime()
+	return mruo
+}
+
+// SetSourceType sets the "source_type" field.
+func (mruo *MessageRecordsUpdateOne) SetSourceType(i int) *MessageRecordsUpdateOne {
+	mruo.mutation.ResetSourceType()
+	mruo.mutation.SetSourceType(i)
+	return mruo
+}
+
+// SetNillableSourceType sets the "source_type" field if the given value is not nil.
+func (mruo *MessageRecordsUpdateOne) SetNillableSourceType(i *int) *MessageRecordsUpdateOne {
+	if i != nil {
+		mruo.SetSourceType(*i)
+	}
+	return mruo
+}
+
+// AddSourceType adds i to the "source_type" field.
+func (mruo *MessageRecordsUpdateOne) AddSourceType(i int) *MessageRecordsUpdateOne {
+	mruo.mutation.AddSourceType(i)
+	return mruo
+}
+
+// SetSourceID sets the "source_id" field.
+func (mruo *MessageRecordsUpdateOne) SetSourceID(u uint64) *MessageRecordsUpdateOne {
+	mruo.mutation.ResetSourceID()
+	mruo.mutation.SetSourceID(u)
+	return mruo
+}
+
+// SetNillableSourceID sets the "source_id" field if the given value is not nil.
+func (mruo *MessageRecordsUpdateOne) SetNillableSourceID(u *uint64) *MessageRecordsUpdateOne {
+	if u != nil {
+		mruo.SetSourceID(*u)
+	}
+	return mruo
+}
+
+// AddSourceID adds u to the "source_id" field.
+func (mruo *MessageRecordsUpdateOne) AddSourceID(u int64) *MessageRecordsUpdateOne {
+	mruo.mutation.AddSourceID(u)
+	return mruo
+}
+
+// ClearSourceID clears the value of the "source_id" field.
+func (mruo *MessageRecordsUpdateOne) ClearSourceID() *MessageRecordsUpdateOne {
+	mruo.mutation.ClearSourceID()
+	return mruo
+}
+
+// SetSubSourceID sets the "sub_source_id" field.
+func (mruo *MessageRecordsUpdateOne) SetSubSourceID(u uint64) *MessageRecordsUpdateOne {
+	mruo.mutation.ResetSubSourceID()
+	mruo.mutation.SetSubSourceID(u)
+	return mruo
+}
+
+// SetNillableSubSourceID sets the "sub_source_id" field if the given value is not nil.
+func (mruo *MessageRecordsUpdateOne) SetNillableSubSourceID(u *uint64) *MessageRecordsUpdateOne {
+	if u != nil {
+		mruo.SetSubSourceID(*u)
+	}
+	return mruo
+}
+
+// AddSubSourceID adds u to the "sub_source_id" field.
+func (mruo *MessageRecordsUpdateOne) AddSubSourceID(u int64) *MessageRecordsUpdateOne {
+	mruo.mutation.AddSubSourceID(u)
+	return mruo
+}
+
+// ClearSubSourceID clears the value of the "sub_source_id" field.
+func (mruo *MessageRecordsUpdateOne) ClearSubSourceID() *MessageRecordsUpdateOne {
+	mruo.mutation.ClearSubSourceID()
+	return mruo
+}
+
+// Mutation returns the MessageRecordsMutation object of the builder.
+func (mruo *MessageRecordsUpdateOne) Mutation() *MessageRecordsMutation {
+	return mruo.mutation
+}
+
+// Where appends a list predicates to the MessageRecordsUpdate builder.
+func (mruo *MessageRecordsUpdateOne) Where(ps ...predicate.MessageRecords) *MessageRecordsUpdateOne {
+	mruo.mutation.Where(ps...)
+	return mruo
+}
+
+// Select allows selecting one or more fields (columns) of the returned entity.
+// The default is selecting all fields defined in the entity schema.
+func (mruo *MessageRecordsUpdateOne) Select(field string, fields ...string) *MessageRecordsUpdateOne {
+	mruo.fields = append([]string{field}, fields...)
+	return mruo
+}
+
+// Save executes the query and returns the updated MessageRecords entity.
+func (mruo *MessageRecordsUpdateOne) Save(ctx context.Context) (*MessageRecords, error) {
+	mruo.defaults()
+	return withHooks(ctx, mruo.sqlSave, mruo.mutation, mruo.hooks)
+}
+
+// SaveX is like Save, but panics if an error occurs.
+func (mruo *MessageRecordsUpdateOne) SaveX(ctx context.Context) *MessageRecords {
+	node, err := mruo.Save(ctx)
+	if err != nil {
+		panic(err)
+	}
+	return node
+}
+
+// Exec executes the query on the entity.
+func (mruo *MessageRecordsUpdateOne) Exec(ctx context.Context) error {
+	_, err := mruo.Save(ctx)
+	return err
+}
+
+// ExecX is like Exec, but panics if an error occurs.
+func (mruo *MessageRecordsUpdateOne) ExecX(ctx context.Context) {
+	if err := mruo.Exec(ctx); err != nil {
+		panic(err)
+	}
+}
+
+// defaults sets the default values of the builder before save.
+func (mruo *MessageRecordsUpdateOne) defaults() {
+	if _, ok := mruo.mutation.UpdatedAt(); !ok {
+		v := messagerecords.UpdateDefaultUpdatedAt()
+		mruo.mutation.SetUpdatedAt(v)
+	}
+}
+
+func (mruo *MessageRecordsUpdateOne) sqlSave(ctx context.Context) (_node *MessageRecords, err error) {
+	_spec := sqlgraph.NewUpdateSpec(messagerecords.Table, messagerecords.Columns, sqlgraph.NewFieldSpec(messagerecords.FieldID, field.TypeUint64))
+	id, ok := mruo.mutation.ID()
+	if !ok {
+		return nil, &ValidationError{Name: "id", err: errors.New(`ent: missing "MessageRecords.id" for update`)}
+	}
+	_spec.Node.ID.Value = id
+	if fields := mruo.fields; len(fields) > 0 {
+		_spec.Node.Columns = make([]string, 0, len(fields))
+		_spec.Node.Columns = append(_spec.Node.Columns, messagerecords.FieldID)
+		for _, f := range fields {
+			if !messagerecords.ValidColumn(f) {
+				return nil, &ValidationError{Name: f, err: fmt.Errorf("ent: invalid field %q for query", f)}
+			}
+			if f != messagerecords.FieldID {
+				_spec.Node.Columns = append(_spec.Node.Columns, f)
+			}
+		}
+	}
+	if ps := mruo.mutation.predicates; len(ps) > 0 {
+		_spec.Predicate = func(selector *sql.Selector) {
+			for i := range ps {
+				ps[i](selector)
+			}
+		}
+	}
+	if value, ok := mruo.mutation.UpdatedAt(); ok {
+		_spec.SetField(messagerecords.FieldUpdatedAt, field.TypeTime, value)
+	}
+	if value, ok := mruo.mutation.Status(); ok {
+		_spec.SetField(messagerecords.FieldStatus, field.TypeUint8, value)
+	}
+	if value, ok := mruo.mutation.AddedStatus(); ok {
+		_spec.AddField(messagerecords.FieldStatus, field.TypeUint8, value)
+	}
+	if mruo.mutation.StatusCleared() {
+		_spec.ClearField(messagerecords.FieldStatus, field.TypeUint8)
+	}
+	if value, ok := mruo.mutation.BotWxid(); ok {
+		_spec.SetField(messagerecords.FieldBotWxid, field.TypeString, value)
+	}
+	if value, ok := mruo.mutation.ContactID(); ok {
+		_spec.SetField(messagerecords.FieldContactID, field.TypeUint64, value)
+	}
+	if value, ok := mruo.mutation.AddedContactID(); ok {
+		_spec.AddField(messagerecords.FieldContactID, field.TypeUint64, value)
+	}
+	if mruo.mutation.ContactIDCleared() {
+		_spec.ClearField(messagerecords.FieldContactID, field.TypeUint64)
+	}
+	if value, ok := mruo.mutation.ContactType(); ok {
+		_spec.SetField(messagerecords.FieldContactType, field.TypeInt, value)
+	}
+	if value, ok := mruo.mutation.AddedContactType(); ok {
+		_spec.AddField(messagerecords.FieldContactType, field.TypeInt, value)
+	}
+	if value, ok := mruo.mutation.ContactWxid(); ok {
+		_spec.SetField(messagerecords.FieldContactWxid, field.TypeString, value)
+	}
+	if value, ok := mruo.mutation.ContentType(); ok {
+		_spec.SetField(messagerecords.FieldContentType, field.TypeInt, value)
+	}
+	if value, ok := mruo.mutation.AddedContentType(); ok {
+		_spec.AddField(messagerecords.FieldContentType, field.TypeInt, value)
+	}
+	if value, ok := mruo.mutation.Content(); ok {
+		_spec.SetField(messagerecords.FieldContent, field.TypeString, value)
+	}
+	if value, ok := mruo.mutation.ErrorDetail(); ok {
+		_spec.SetField(messagerecords.FieldErrorDetail, field.TypeString, value)
+	}
+	if value, ok := mruo.mutation.SendTime(); ok {
+		_spec.SetField(messagerecords.FieldSendTime, field.TypeTime, value)
+	}
+	if mruo.mutation.SendTimeCleared() {
+		_spec.ClearField(messagerecords.FieldSendTime, field.TypeTime)
+	}
+	if value, ok := mruo.mutation.SourceType(); ok {
+		_spec.SetField(messagerecords.FieldSourceType, field.TypeInt, value)
+	}
+	if value, ok := mruo.mutation.AddedSourceType(); ok {
+		_spec.AddField(messagerecords.FieldSourceType, field.TypeInt, value)
+	}
+	if value, ok := mruo.mutation.SourceID(); ok {
+		_spec.SetField(messagerecords.FieldSourceID, field.TypeUint64, value)
+	}
+	if value, ok := mruo.mutation.AddedSourceID(); ok {
+		_spec.AddField(messagerecords.FieldSourceID, field.TypeUint64, value)
+	}
+	if mruo.mutation.SourceIDCleared() {
+		_spec.ClearField(messagerecords.FieldSourceID, field.TypeUint64)
+	}
+	if value, ok := mruo.mutation.SubSourceID(); ok {
+		_spec.SetField(messagerecords.FieldSubSourceID, field.TypeUint64, value)
+	}
+	if value, ok := mruo.mutation.AddedSubSourceID(); ok {
+		_spec.AddField(messagerecords.FieldSubSourceID, field.TypeUint64, value)
+	}
+	if mruo.mutation.SubSourceIDCleared() {
+		_spec.ClearField(messagerecords.FieldSubSourceID, field.TypeUint64)
+	}
+	_node = &MessageRecords{config: mruo.config}
+	_spec.Assign = _node.assignValues
+	_spec.ScanValues = _node.scanValues
+	if err = sqlgraph.UpdateNode(ctx, mruo.driver, _spec); err != nil {
+		if _, ok := err.(*sqlgraph.NotFoundError); ok {
+			err = &NotFoundError{messagerecords.Label}
+		} else if sqlgraph.IsConstraintError(err) {
+			err = &ConstraintError{msg: err.Error(), wrap: err}
+		}
+		return nil, err
+	}
+	mruo.mutation.done = true
+	return _node, nil
+}

+ 28 - 0
ent/migrate/schema.go

@@ -9,6 +9,30 @@ import (
 )
 
 var (
+	// MessageRecordsColumns holds the columns for the "message_records" table.
+	MessageRecordsColumns = []*schema.Column{
+		{Name: "id", Type: field.TypeUint64, Increment: true},
+		{Name: "created_at", Type: field.TypeTime, Comment: "Create Time | 创建日期"},
+		{Name: "updated_at", Type: field.TypeTime, Comment: "Update Time | 修改日期"},
+		{Name: "status", Type: field.TypeUint8, Nullable: true, Comment: "Status 1: normal 2: ban | 状态 1 正常 2 禁用", Default: 1},
+		{Name: "bot_wxid", Type: field.TypeString, Comment: "机器人微信 id"},
+		{Name: "contact_id", Type: field.TypeUint64, Nullable: true, Comment: "联系人 id"},
+		{Name: "contact_type", Type: field.TypeInt, Comment: "类型:1好友,2群组,3企业微信联系人", Default: 1},
+		{Name: "contact_wxid", Type: field.TypeString, Comment: "接收方微信 id", Default: ""},
+		{Name: "content_type", Type: field.TypeInt, Comment: "内容类型 1 文本 2 文件", Default: 1},
+		{Name: "content", Type: field.TypeString, Comment: "发送内容", Default: ""},
+		{Name: "error_detail", Type: field.TypeString, Comment: "异常原因", Default: ""},
+		{Name: "send_time", Type: field.TypeTime, Nullable: true, Comment: "发送时间"},
+		{Name: "source_type", Type: field.TypeInt, Comment: "源类型 1 点发 2 群发 3 SOP", Default: 1},
+		{Name: "source_id", Type: field.TypeUint64, Nullable: true, Comment: "源 ID", Default: 1},
+		{Name: "sub_source_id", Type: field.TypeUint64, Nullable: true, Comment: "次源 ID", Default: 1},
+	}
+	// MessageRecordsTable holds the schema information for the "message_records" table.
+	MessageRecordsTable = &schema.Table{
+		Name:       "message_records",
+		Columns:    MessageRecordsColumns,
+		PrimaryKey: []*schema.Column{MessageRecordsColumns[0]},
+	}
 	// SysTasksColumns holds the columns for the "sys_tasks" table.
 	SysTasksColumns = []*schema.Column{
 		{Name: "id", Type: field.TypeUint64, Increment: true},
@@ -58,12 +82,16 @@ var (
 	}
 	// Tables holds all the tables in the schema.
 	Tables = []*schema.Table{
+		MessageRecordsTable,
 		SysTasksTable,
 		SysTaskLogsTable,
 	}
 )
 
 func init() {
+	MessageRecordsTable.Annotation = &entsql.Annotation{
+		Table: "message_records",
+	}
 	SysTasksTable.Annotation = &entsql.Annotation{
 		Table: "sys_tasks",
 	}

+ 1374 - 2
ent/mutation.go

@@ -11,6 +11,7 @@ import (
 
 	"entgo.io/ent"
 	"entgo.io/ent/dialect/sql"
+	"github.com/suyuan32/simple-admin-job/ent/messagerecords"
 	"github.com/suyuan32/simple-admin-job/ent/predicate"
 	"github.com/suyuan32/simple-admin-job/ent/task"
 	"github.com/suyuan32/simple-admin-job/ent/tasklog"
@@ -25,10 +26,1381 @@ const (
 	OpUpdateOne = ent.OpUpdateOne
 
 	// Node types.
-	TypeTask    = "Task"
-	TypeTaskLog = "TaskLog"
+	TypeMessageRecords = "MessageRecords"
+	TypeTask           = "Task"
+	TypeTaskLog        = "TaskLog"
 )
 
+// MessageRecordsMutation represents an operation that mutates the MessageRecords nodes in the graph.
+type MessageRecordsMutation struct {
+	config
+	op               Op
+	typ              string
+	id               *uint64
+	created_at       *time.Time
+	updated_at       *time.Time
+	status           *uint8
+	addstatus        *int8
+	bot_wxid         *string
+	contact_id       *uint64
+	addcontact_id    *int64
+	contact_type     *int
+	addcontact_type  *int
+	contact_wxid     *string
+	content_type     *int
+	addcontent_type  *int
+	content          *string
+	error_detail     *string
+	send_time        *time.Time
+	source_type      *int
+	addsource_type   *int
+	source_id        *uint64
+	addsource_id     *int64
+	sub_source_id    *uint64
+	addsub_source_id *int64
+	clearedFields    map[string]struct{}
+	done             bool
+	oldValue         func(context.Context) (*MessageRecords, error)
+	predicates       []predicate.MessageRecords
+}
+
+var _ ent.Mutation = (*MessageRecordsMutation)(nil)
+
+// messagerecordsOption allows management of the mutation configuration using functional options.
+type messagerecordsOption func(*MessageRecordsMutation)
+
+// newMessageRecordsMutation creates new mutation for the MessageRecords entity.
+func newMessageRecordsMutation(c config, op Op, opts ...messagerecordsOption) *MessageRecordsMutation {
+	m := &MessageRecordsMutation{
+		config:        c,
+		op:            op,
+		typ:           TypeMessageRecords,
+		clearedFields: make(map[string]struct{}),
+	}
+	for _, opt := range opts {
+		opt(m)
+	}
+	return m
+}
+
+// withMessageRecordsID sets the ID field of the mutation.
+func withMessageRecordsID(id uint64) messagerecordsOption {
+	return func(m *MessageRecordsMutation) {
+		var (
+			err   error
+			once  sync.Once
+			value *MessageRecords
+		)
+		m.oldValue = func(ctx context.Context) (*MessageRecords, error) {
+			once.Do(func() {
+				if m.done {
+					err = errors.New("querying old values post mutation is not allowed")
+				} else {
+					value, err = m.Client().MessageRecords.Get(ctx, id)
+				}
+			})
+			return value, err
+		}
+		m.id = &id
+	}
+}
+
+// withMessageRecords sets the old MessageRecords of the mutation.
+func withMessageRecords(node *MessageRecords) messagerecordsOption {
+	return func(m *MessageRecordsMutation) {
+		m.oldValue = func(context.Context) (*MessageRecords, 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 MessageRecordsMutation) 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 MessageRecordsMutation) 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 MessageRecords entities.
+func (m *MessageRecordsMutation) 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 *MessageRecordsMutation) 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 *MessageRecordsMutation) 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().MessageRecords.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 *MessageRecordsMutation) SetCreatedAt(t time.Time) {
+	m.created_at = &t
+}
+
+// CreatedAt returns the value of the "created_at" field in the mutation.
+func (m *MessageRecordsMutation) 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 MessageRecords entity.
+// If the MessageRecords 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 *MessageRecordsMutation) 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 *MessageRecordsMutation) ResetCreatedAt() {
+	m.created_at = nil
+}
+
+// SetUpdatedAt sets the "updated_at" field.
+func (m *MessageRecordsMutation) SetUpdatedAt(t time.Time) {
+	m.updated_at = &t
+}
+
+// UpdatedAt returns the value of the "updated_at" field in the mutation.
+func (m *MessageRecordsMutation) 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 MessageRecords entity.
+// If the MessageRecords 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 *MessageRecordsMutation) 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 *MessageRecordsMutation) ResetUpdatedAt() {
+	m.updated_at = nil
+}
+
+// SetStatus sets the "status" field.
+func (m *MessageRecordsMutation) SetStatus(u uint8) {
+	m.status = &u
+	m.addstatus = nil
+}
+
+// Status returns the value of the "status" field in the mutation.
+func (m *MessageRecordsMutation) Status() (r uint8, exists bool) {
+	v := m.status
+	if v == nil {
+		return
+	}
+	return *v, true
+}
+
+// OldStatus returns the old "status" field's value of the MessageRecords entity.
+// If the MessageRecords 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 *MessageRecordsMutation) OldStatus(ctx context.Context) (v uint8, err error) {
+	if !m.op.Is(OpUpdateOne) {
+		return v, errors.New("OldStatus is only allowed on UpdateOne operations")
+	}
+	if m.id == nil || m.oldValue == nil {
+		return v, errors.New("OldStatus requires an ID field in the mutation")
+	}
+	oldValue, err := m.oldValue(ctx)
+	if err != nil {
+		return v, fmt.Errorf("querying old value for OldStatus: %w", err)
+	}
+	return oldValue.Status, nil
+}
+
+// AddStatus adds u to the "status" field.
+func (m *MessageRecordsMutation) AddStatus(u int8) {
+	if m.addstatus != nil {
+		*m.addstatus += u
+	} else {
+		m.addstatus = &u
+	}
+}
+
+// AddedStatus returns the value that was added to the "status" field in this mutation.
+func (m *MessageRecordsMutation) AddedStatus() (r int8, exists bool) {
+	v := m.addstatus
+	if v == nil {
+		return
+	}
+	return *v, true
+}
+
+// ClearStatus clears the value of the "status" field.
+func (m *MessageRecordsMutation) ClearStatus() {
+	m.status = nil
+	m.addstatus = nil
+	m.clearedFields[messagerecords.FieldStatus] = struct{}{}
+}
+
+// StatusCleared returns if the "status" field was cleared in this mutation.
+func (m *MessageRecordsMutation) StatusCleared() bool {
+	_, ok := m.clearedFields[messagerecords.FieldStatus]
+	return ok
+}
+
+// ResetStatus resets all changes to the "status" field.
+func (m *MessageRecordsMutation) ResetStatus() {
+	m.status = nil
+	m.addstatus = nil
+	delete(m.clearedFields, messagerecords.FieldStatus)
+}
+
+// SetBotWxid sets the "bot_wxid" field.
+func (m *MessageRecordsMutation) SetBotWxid(s string) {
+	m.bot_wxid = &s
+}
+
+// BotWxid returns the value of the "bot_wxid" field in the mutation.
+func (m *MessageRecordsMutation) BotWxid() (r string, exists bool) {
+	v := m.bot_wxid
+	if v == nil {
+		return
+	}
+	return *v, true
+}
+
+// OldBotWxid returns the old "bot_wxid" field's value of the MessageRecords entity.
+// If the MessageRecords 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 *MessageRecordsMutation) OldBotWxid(ctx context.Context) (v string, err error) {
+	if !m.op.Is(OpUpdateOne) {
+		return v, errors.New("OldBotWxid is only allowed on UpdateOne operations")
+	}
+	if m.id == nil || m.oldValue == nil {
+		return v, errors.New("OldBotWxid requires an ID field in the mutation")
+	}
+	oldValue, err := m.oldValue(ctx)
+	if err != nil {
+		return v, fmt.Errorf("querying old value for OldBotWxid: %w", err)
+	}
+	return oldValue.BotWxid, nil
+}
+
+// ResetBotWxid resets all changes to the "bot_wxid" field.
+func (m *MessageRecordsMutation) ResetBotWxid() {
+	m.bot_wxid = nil
+}
+
+// SetContactID sets the "contact_id" field.
+func (m *MessageRecordsMutation) SetContactID(u uint64) {
+	m.contact_id = &u
+	m.addcontact_id = nil
+}
+
+// ContactID returns the value of the "contact_id" field in the mutation.
+func (m *MessageRecordsMutation) ContactID() (r uint64, exists bool) {
+	v := m.contact_id
+	if v == nil {
+		return
+	}
+	return *v, true
+}
+
+// OldContactID returns the old "contact_id" field's value of the MessageRecords entity.
+// If the MessageRecords 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 *MessageRecordsMutation) OldContactID(ctx context.Context) (v uint64, err error) {
+	if !m.op.Is(OpUpdateOne) {
+		return v, errors.New("OldContactID is only allowed on UpdateOne operations")
+	}
+	if m.id == nil || m.oldValue == nil {
+		return v, errors.New("OldContactID requires an ID field in the mutation")
+	}
+	oldValue, err := m.oldValue(ctx)
+	if err != nil {
+		return v, fmt.Errorf("querying old value for OldContactID: %w", err)
+	}
+	return oldValue.ContactID, nil
+}
+
+// AddContactID adds u to the "contact_id" field.
+func (m *MessageRecordsMutation) AddContactID(u int64) {
+	if m.addcontact_id != nil {
+		*m.addcontact_id += u
+	} else {
+		m.addcontact_id = &u
+	}
+}
+
+// AddedContactID returns the value that was added to the "contact_id" field in this mutation.
+func (m *MessageRecordsMutation) AddedContactID() (r int64, exists bool) {
+	v := m.addcontact_id
+	if v == nil {
+		return
+	}
+	return *v, true
+}
+
+// ClearContactID clears the value of the "contact_id" field.
+func (m *MessageRecordsMutation) ClearContactID() {
+	m.contact_id = nil
+	m.addcontact_id = nil
+	m.clearedFields[messagerecords.FieldContactID] = struct{}{}
+}
+
+// ContactIDCleared returns if the "contact_id" field was cleared in this mutation.
+func (m *MessageRecordsMutation) ContactIDCleared() bool {
+	_, ok := m.clearedFields[messagerecords.FieldContactID]
+	return ok
+}
+
+// ResetContactID resets all changes to the "contact_id" field.
+func (m *MessageRecordsMutation) ResetContactID() {
+	m.contact_id = nil
+	m.addcontact_id = nil
+	delete(m.clearedFields, messagerecords.FieldContactID)
+}
+
+// SetContactType sets the "contact_type" field.
+func (m *MessageRecordsMutation) SetContactType(i int) {
+	m.contact_type = &i
+	m.addcontact_type = nil
+}
+
+// ContactType returns the value of the "contact_type" field in the mutation.
+func (m *MessageRecordsMutation) ContactType() (r int, exists bool) {
+	v := m.contact_type
+	if v == nil {
+		return
+	}
+	return *v, true
+}
+
+// OldContactType returns the old "contact_type" field's value of the MessageRecords entity.
+// If the MessageRecords 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 *MessageRecordsMutation) OldContactType(ctx context.Context) (v int, err error) {
+	if !m.op.Is(OpUpdateOne) {
+		return v, errors.New("OldContactType is only allowed on UpdateOne operations")
+	}
+	if m.id == nil || m.oldValue == nil {
+		return v, errors.New("OldContactType requires an ID field in the mutation")
+	}
+	oldValue, err := m.oldValue(ctx)
+	if err != nil {
+		return v, fmt.Errorf("querying old value for OldContactType: %w", err)
+	}
+	return oldValue.ContactType, nil
+}
+
+// AddContactType adds i to the "contact_type" field.
+func (m *MessageRecordsMutation) AddContactType(i int) {
+	if m.addcontact_type != nil {
+		*m.addcontact_type += i
+	} else {
+		m.addcontact_type = &i
+	}
+}
+
+// AddedContactType returns the value that was added to the "contact_type" field in this mutation.
+func (m *MessageRecordsMutation) AddedContactType() (r int, exists bool) {
+	v := m.addcontact_type
+	if v == nil {
+		return
+	}
+	return *v, true
+}
+
+// ResetContactType resets all changes to the "contact_type" field.
+func (m *MessageRecordsMutation) ResetContactType() {
+	m.contact_type = nil
+	m.addcontact_type = nil
+}
+
+// SetContactWxid sets the "contact_wxid" field.
+func (m *MessageRecordsMutation) SetContactWxid(s string) {
+	m.contact_wxid = &s
+}
+
+// ContactWxid returns the value of the "contact_wxid" field in the mutation.
+func (m *MessageRecordsMutation) ContactWxid() (r string, exists bool) {
+	v := m.contact_wxid
+	if v == nil {
+		return
+	}
+	return *v, true
+}
+
+// OldContactWxid returns the old "contact_wxid" field's value of the MessageRecords entity.
+// If the MessageRecords 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 *MessageRecordsMutation) OldContactWxid(ctx context.Context) (v string, err error) {
+	if !m.op.Is(OpUpdateOne) {
+		return v, errors.New("OldContactWxid is only allowed on UpdateOne operations")
+	}
+	if m.id == nil || m.oldValue == nil {
+		return v, errors.New("OldContactWxid requires an ID field in the mutation")
+	}
+	oldValue, err := m.oldValue(ctx)
+	if err != nil {
+		return v, fmt.Errorf("querying old value for OldContactWxid: %w", err)
+	}
+	return oldValue.ContactWxid, nil
+}
+
+// ResetContactWxid resets all changes to the "contact_wxid" field.
+func (m *MessageRecordsMutation) ResetContactWxid() {
+	m.contact_wxid = nil
+}
+
+// SetContentType sets the "content_type" field.
+func (m *MessageRecordsMutation) SetContentType(i int) {
+	m.content_type = &i
+	m.addcontent_type = nil
+}
+
+// ContentType returns the value of the "content_type" field in the mutation.
+func (m *MessageRecordsMutation) ContentType() (r int, exists bool) {
+	v := m.content_type
+	if v == nil {
+		return
+	}
+	return *v, true
+}
+
+// OldContentType returns the old "content_type" field's value of the MessageRecords entity.
+// If the MessageRecords 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 *MessageRecordsMutation) OldContentType(ctx context.Context) (v int, err error) {
+	if !m.op.Is(OpUpdateOne) {
+		return v, errors.New("OldContentType is only allowed on UpdateOne operations")
+	}
+	if m.id == nil || m.oldValue == nil {
+		return v, errors.New("OldContentType requires an ID field in the mutation")
+	}
+	oldValue, err := m.oldValue(ctx)
+	if err != nil {
+		return v, fmt.Errorf("querying old value for OldContentType: %w", err)
+	}
+	return oldValue.ContentType, nil
+}
+
+// AddContentType adds i to the "content_type" field.
+func (m *MessageRecordsMutation) AddContentType(i int) {
+	if m.addcontent_type != nil {
+		*m.addcontent_type += i
+	} else {
+		m.addcontent_type = &i
+	}
+}
+
+// AddedContentType returns the value that was added to the "content_type" field in this mutation.
+func (m *MessageRecordsMutation) AddedContentType() (r int, exists bool) {
+	v := m.addcontent_type
+	if v == nil {
+		return
+	}
+	return *v, true
+}
+
+// ResetContentType resets all changes to the "content_type" field.
+func (m *MessageRecordsMutation) ResetContentType() {
+	m.content_type = nil
+	m.addcontent_type = nil
+}
+
+// SetContent sets the "content" field.
+func (m *MessageRecordsMutation) SetContent(s string) {
+	m.content = &s
+}
+
+// Content returns the value of the "content" field in the mutation.
+func (m *MessageRecordsMutation) Content() (r string, exists bool) {
+	v := m.content
+	if v == nil {
+		return
+	}
+	return *v, true
+}
+
+// OldContent returns the old "content" field's value of the MessageRecords entity.
+// If the MessageRecords 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 *MessageRecordsMutation) OldContent(ctx context.Context) (v string, err error) {
+	if !m.op.Is(OpUpdateOne) {
+		return v, errors.New("OldContent is only allowed on UpdateOne operations")
+	}
+	if m.id == nil || m.oldValue == nil {
+		return v, errors.New("OldContent requires an ID field in the mutation")
+	}
+	oldValue, err := m.oldValue(ctx)
+	if err != nil {
+		return v, fmt.Errorf("querying old value for OldContent: %w", err)
+	}
+	return oldValue.Content, nil
+}
+
+// ResetContent resets all changes to the "content" field.
+func (m *MessageRecordsMutation) ResetContent() {
+	m.content = nil
+}
+
+// SetErrorDetail sets the "error_detail" field.
+func (m *MessageRecordsMutation) SetErrorDetail(s string) {
+	m.error_detail = &s
+}
+
+// ErrorDetail returns the value of the "error_detail" field in the mutation.
+func (m *MessageRecordsMutation) ErrorDetail() (r string, exists bool) {
+	v := m.error_detail
+	if v == nil {
+		return
+	}
+	return *v, true
+}
+
+// OldErrorDetail returns the old "error_detail" field's value of the MessageRecords entity.
+// If the MessageRecords 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 *MessageRecordsMutation) OldErrorDetail(ctx context.Context) (v string, err error) {
+	if !m.op.Is(OpUpdateOne) {
+		return v, errors.New("OldErrorDetail is only allowed on UpdateOne operations")
+	}
+	if m.id == nil || m.oldValue == nil {
+		return v, errors.New("OldErrorDetail requires an ID field in the mutation")
+	}
+	oldValue, err := m.oldValue(ctx)
+	if err != nil {
+		return v, fmt.Errorf("querying old value for OldErrorDetail: %w", err)
+	}
+	return oldValue.ErrorDetail, nil
+}
+
+// ResetErrorDetail resets all changes to the "error_detail" field.
+func (m *MessageRecordsMutation) ResetErrorDetail() {
+	m.error_detail = nil
+}
+
+// SetSendTime sets the "send_time" field.
+func (m *MessageRecordsMutation) SetSendTime(t time.Time) {
+	m.send_time = &t
+}
+
+// SendTime returns the value of the "send_time" field in the mutation.
+func (m *MessageRecordsMutation) SendTime() (r time.Time, exists bool) {
+	v := m.send_time
+	if v == nil {
+		return
+	}
+	return *v, true
+}
+
+// OldSendTime returns the old "send_time" field's value of the MessageRecords entity.
+// If the MessageRecords 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 *MessageRecordsMutation) OldSendTime(ctx context.Context) (v time.Time, err error) {
+	if !m.op.Is(OpUpdateOne) {
+		return v, errors.New("OldSendTime is only allowed on UpdateOne operations")
+	}
+	if m.id == nil || m.oldValue == nil {
+		return v, errors.New("OldSendTime requires an ID field in the mutation")
+	}
+	oldValue, err := m.oldValue(ctx)
+	if err != nil {
+		return v, fmt.Errorf("querying old value for OldSendTime: %w", err)
+	}
+	return oldValue.SendTime, nil
+}
+
+// ClearSendTime clears the value of the "send_time" field.
+func (m *MessageRecordsMutation) ClearSendTime() {
+	m.send_time = nil
+	m.clearedFields[messagerecords.FieldSendTime] = struct{}{}
+}
+
+// SendTimeCleared returns if the "send_time" field was cleared in this mutation.
+func (m *MessageRecordsMutation) SendTimeCleared() bool {
+	_, ok := m.clearedFields[messagerecords.FieldSendTime]
+	return ok
+}
+
+// ResetSendTime resets all changes to the "send_time" field.
+func (m *MessageRecordsMutation) ResetSendTime() {
+	m.send_time = nil
+	delete(m.clearedFields, messagerecords.FieldSendTime)
+}
+
+// SetSourceType sets the "source_type" field.
+func (m *MessageRecordsMutation) SetSourceType(i int) {
+	m.source_type = &i
+	m.addsource_type = nil
+}
+
+// SourceType returns the value of the "source_type" field in the mutation.
+func (m *MessageRecordsMutation) SourceType() (r int, exists bool) {
+	v := m.source_type
+	if v == nil {
+		return
+	}
+	return *v, true
+}
+
+// OldSourceType returns the old "source_type" field's value of the MessageRecords entity.
+// If the MessageRecords 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 *MessageRecordsMutation) OldSourceType(ctx context.Context) (v int, err error) {
+	if !m.op.Is(OpUpdateOne) {
+		return v, errors.New("OldSourceType is only allowed on UpdateOne operations")
+	}
+	if m.id == nil || m.oldValue == nil {
+		return v, errors.New("OldSourceType requires an ID field in the mutation")
+	}
+	oldValue, err := m.oldValue(ctx)
+	if err != nil {
+		return v, fmt.Errorf("querying old value for OldSourceType: %w", err)
+	}
+	return oldValue.SourceType, nil
+}
+
+// AddSourceType adds i to the "source_type" field.
+func (m *MessageRecordsMutation) AddSourceType(i int) {
+	if m.addsource_type != nil {
+		*m.addsource_type += i
+	} else {
+		m.addsource_type = &i
+	}
+}
+
+// AddedSourceType returns the value that was added to the "source_type" field in this mutation.
+func (m *MessageRecordsMutation) AddedSourceType() (r int, exists bool) {
+	v := m.addsource_type
+	if v == nil {
+		return
+	}
+	return *v, true
+}
+
+// ResetSourceType resets all changes to the "source_type" field.
+func (m *MessageRecordsMutation) ResetSourceType() {
+	m.source_type = nil
+	m.addsource_type = nil
+}
+
+// SetSourceID sets the "source_id" field.
+func (m *MessageRecordsMutation) SetSourceID(u uint64) {
+	m.source_id = &u
+	m.addsource_id = nil
+}
+
+// SourceID returns the value of the "source_id" field in the mutation.
+func (m *MessageRecordsMutation) SourceID() (r uint64, exists bool) {
+	v := m.source_id
+	if v == nil {
+		return
+	}
+	return *v, true
+}
+
+// OldSourceID returns the old "source_id" field's value of the MessageRecords entity.
+// If the MessageRecords 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 *MessageRecordsMutation) OldSourceID(ctx context.Context) (v uint64, err error) {
+	if !m.op.Is(OpUpdateOne) {
+		return v, errors.New("OldSourceID is only allowed on UpdateOne operations")
+	}
+	if m.id == nil || m.oldValue == nil {
+		return v, errors.New("OldSourceID requires an ID field in the mutation")
+	}
+	oldValue, err := m.oldValue(ctx)
+	if err != nil {
+		return v, fmt.Errorf("querying old value for OldSourceID: %w", err)
+	}
+	return oldValue.SourceID, nil
+}
+
+// AddSourceID adds u to the "source_id" field.
+func (m *MessageRecordsMutation) AddSourceID(u int64) {
+	if m.addsource_id != nil {
+		*m.addsource_id += u
+	} else {
+		m.addsource_id = &u
+	}
+}
+
+// AddedSourceID returns the value that was added to the "source_id" field in this mutation.
+func (m *MessageRecordsMutation) AddedSourceID() (r int64, exists bool) {
+	v := m.addsource_id
+	if v == nil {
+		return
+	}
+	return *v, true
+}
+
+// ClearSourceID clears the value of the "source_id" field.
+func (m *MessageRecordsMutation) ClearSourceID() {
+	m.source_id = nil
+	m.addsource_id = nil
+	m.clearedFields[messagerecords.FieldSourceID] = struct{}{}
+}
+
+// SourceIDCleared returns if the "source_id" field was cleared in this mutation.
+func (m *MessageRecordsMutation) SourceIDCleared() bool {
+	_, ok := m.clearedFields[messagerecords.FieldSourceID]
+	return ok
+}
+
+// ResetSourceID resets all changes to the "source_id" field.
+func (m *MessageRecordsMutation) ResetSourceID() {
+	m.source_id = nil
+	m.addsource_id = nil
+	delete(m.clearedFields, messagerecords.FieldSourceID)
+}
+
+// SetSubSourceID sets the "sub_source_id" field.
+func (m *MessageRecordsMutation) SetSubSourceID(u uint64) {
+	m.sub_source_id = &u
+	m.addsub_source_id = nil
+}
+
+// SubSourceID returns the value of the "sub_source_id" field in the mutation.
+func (m *MessageRecordsMutation) SubSourceID() (r uint64, exists bool) {
+	v := m.sub_source_id
+	if v == nil {
+		return
+	}
+	return *v, true
+}
+
+// OldSubSourceID returns the old "sub_source_id" field's value of the MessageRecords entity.
+// If the MessageRecords 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 *MessageRecordsMutation) OldSubSourceID(ctx context.Context) (v uint64, err error) {
+	if !m.op.Is(OpUpdateOne) {
+		return v, errors.New("OldSubSourceID is only allowed on UpdateOne operations")
+	}
+	if m.id == nil || m.oldValue == nil {
+		return v, errors.New("OldSubSourceID requires an ID field in the mutation")
+	}
+	oldValue, err := m.oldValue(ctx)
+	if err != nil {
+		return v, fmt.Errorf("querying old value for OldSubSourceID: %w", err)
+	}
+	return oldValue.SubSourceID, nil
+}
+
+// AddSubSourceID adds u to the "sub_source_id" field.
+func (m *MessageRecordsMutation) AddSubSourceID(u int64) {
+	if m.addsub_source_id != nil {
+		*m.addsub_source_id += u
+	} else {
+		m.addsub_source_id = &u
+	}
+}
+
+// AddedSubSourceID returns the value that was added to the "sub_source_id" field in this mutation.
+func (m *MessageRecordsMutation) AddedSubSourceID() (r int64, exists bool) {
+	v := m.addsub_source_id
+	if v == nil {
+		return
+	}
+	return *v, true
+}
+
+// ClearSubSourceID clears the value of the "sub_source_id" field.
+func (m *MessageRecordsMutation) ClearSubSourceID() {
+	m.sub_source_id = nil
+	m.addsub_source_id = nil
+	m.clearedFields[messagerecords.FieldSubSourceID] = struct{}{}
+}
+
+// SubSourceIDCleared returns if the "sub_source_id" field was cleared in this mutation.
+func (m *MessageRecordsMutation) SubSourceIDCleared() bool {
+	_, ok := m.clearedFields[messagerecords.FieldSubSourceID]
+	return ok
+}
+
+// ResetSubSourceID resets all changes to the "sub_source_id" field.
+func (m *MessageRecordsMutation) ResetSubSourceID() {
+	m.sub_source_id = nil
+	m.addsub_source_id = nil
+	delete(m.clearedFields, messagerecords.FieldSubSourceID)
+}
+
+// Where appends a list predicates to the MessageRecordsMutation builder.
+func (m *MessageRecordsMutation) Where(ps ...predicate.MessageRecords) {
+	m.predicates = append(m.predicates, ps...)
+}
+
+// WhereP appends storage-level predicates to the MessageRecordsMutation builder. Using this method,
+// users can use type-assertion to append predicates that do not depend on any generated package.
+func (m *MessageRecordsMutation) WhereP(ps ...func(*sql.Selector)) {
+	p := make([]predicate.MessageRecords, len(ps))
+	for i := range ps {
+		p[i] = ps[i]
+	}
+	m.Where(p...)
+}
+
+// Op returns the operation name.
+func (m *MessageRecordsMutation) Op() Op {
+	return m.op
+}
+
+// SetOp allows setting the mutation operation.
+func (m *MessageRecordsMutation) SetOp(op Op) {
+	m.op = op
+}
+
+// Type returns the node type of this mutation (MessageRecords).
+func (m *MessageRecordsMutation) 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 *MessageRecordsMutation) Fields() []string {
+	fields := make([]string, 0, 14)
+	if m.created_at != nil {
+		fields = append(fields, messagerecords.FieldCreatedAt)
+	}
+	if m.updated_at != nil {
+		fields = append(fields, messagerecords.FieldUpdatedAt)
+	}
+	if m.status != nil {
+		fields = append(fields, messagerecords.FieldStatus)
+	}
+	if m.bot_wxid != nil {
+		fields = append(fields, messagerecords.FieldBotWxid)
+	}
+	if m.contact_id != nil {
+		fields = append(fields, messagerecords.FieldContactID)
+	}
+	if m.contact_type != nil {
+		fields = append(fields, messagerecords.FieldContactType)
+	}
+	if m.contact_wxid != nil {
+		fields = append(fields, messagerecords.FieldContactWxid)
+	}
+	if m.content_type != nil {
+		fields = append(fields, messagerecords.FieldContentType)
+	}
+	if m.content != nil {
+		fields = append(fields, messagerecords.FieldContent)
+	}
+	if m.error_detail != nil {
+		fields = append(fields, messagerecords.FieldErrorDetail)
+	}
+	if m.send_time != nil {
+		fields = append(fields, messagerecords.FieldSendTime)
+	}
+	if m.source_type != nil {
+		fields = append(fields, messagerecords.FieldSourceType)
+	}
+	if m.source_id != nil {
+		fields = append(fields, messagerecords.FieldSourceID)
+	}
+	if m.sub_source_id != nil {
+		fields = append(fields, messagerecords.FieldSubSourceID)
+	}
+	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 *MessageRecordsMutation) Field(name string) (ent.Value, bool) {
+	switch name {
+	case messagerecords.FieldCreatedAt:
+		return m.CreatedAt()
+	case messagerecords.FieldUpdatedAt:
+		return m.UpdatedAt()
+	case messagerecords.FieldStatus:
+		return m.Status()
+	case messagerecords.FieldBotWxid:
+		return m.BotWxid()
+	case messagerecords.FieldContactID:
+		return m.ContactID()
+	case messagerecords.FieldContactType:
+		return m.ContactType()
+	case messagerecords.FieldContactWxid:
+		return m.ContactWxid()
+	case messagerecords.FieldContentType:
+		return m.ContentType()
+	case messagerecords.FieldContent:
+		return m.Content()
+	case messagerecords.FieldErrorDetail:
+		return m.ErrorDetail()
+	case messagerecords.FieldSendTime:
+		return m.SendTime()
+	case messagerecords.FieldSourceType:
+		return m.SourceType()
+	case messagerecords.FieldSourceID:
+		return m.SourceID()
+	case messagerecords.FieldSubSourceID:
+		return m.SubSourceID()
+	}
+	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 *MessageRecordsMutation) OldField(ctx context.Context, name string) (ent.Value, error) {
+	switch name {
+	case messagerecords.FieldCreatedAt:
+		return m.OldCreatedAt(ctx)
+	case messagerecords.FieldUpdatedAt:
+		return m.OldUpdatedAt(ctx)
+	case messagerecords.FieldStatus:
+		return m.OldStatus(ctx)
+	case messagerecords.FieldBotWxid:
+		return m.OldBotWxid(ctx)
+	case messagerecords.FieldContactID:
+		return m.OldContactID(ctx)
+	case messagerecords.FieldContactType:
+		return m.OldContactType(ctx)
+	case messagerecords.FieldContactWxid:
+		return m.OldContactWxid(ctx)
+	case messagerecords.FieldContentType:
+		return m.OldContentType(ctx)
+	case messagerecords.FieldContent:
+		return m.OldContent(ctx)
+	case messagerecords.FieldErrorDetail:
+		return m.OldErrorDetail(ctx)
+	case messagerecords.FieldSendTime:
+		return m.OldSendTime(ctx)
+	case messagerecords.FieldSourceType:
+		return m.OldSourceType(ctx)
+	case messagerecords.FieldSourceID:
+		return m.OldSourceID(ctx)
+	case messagerecords.FieldSubSourceID:
+		return m.OldSubSourceID(ctx)
+	}
+	return nil, fmt.Errorf("unknown MessageRecords 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 *MessageRecordsMutation) SetField(name string, value ent.Value) error {
+	switch name {
+	case messagerecords.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 messagerecords.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 messagerecords.FieldStatus:
+		v, ok := value.(uint8)
+		if !ok {
+			return fmt.Errorf("unexpected type %T for field %s", value, name)
+		}
+		m.SetStatus(v)
+		return nil
+	case messagerecords.FieldBotWxid:
+		v, ok := value.(string)
+		if !ok {
+			return fmt.Errorf("unexpected type %T for field %s", value, name)
+		}
+		m.SetBotWxid(v)
+		return nil
+	case messagerecords.FieldContactID:
+		v, ok := value.(uint64)
+		if !ok {
+			return fmt.Errorf("unexpected type %T for field %s", value, name)
+		}
+		m.SetContactID(v)
+		return nil
+	case messagerecords.FieldContactType:
+		v, ok := value.(int)
+		if !ok {
+			return fmt.Errorf("unexpected type %T for field %s", value, name)
+		}
+		m.SetContactType(v)
+		return nil
+	case messagerecords.FieldContactWxid:
+		v, ok := value.(string)
+		if !ok {
+			return fmt.Errorf("unexpected type %T for field %s", value, name)
+		}
+		m.SetContactWxid(v)
+		return nil
+	case messagerecords.FieldContentType:
+		v, ok := value.(int)
+		if !ok {
+			return fmt.Errorf("unexpected type %T for field %s", value, name)
+		}
+		m.SetContentType(v)
+		return nil
+	case messagerecords.FieldContent:
+		v, ok := value.(string)
+		if !ok {
+			return fmt.Errorf("unexpected type %T for field %s", value, name)
+		}
+		m.SetContent(v)
+		return nil
+	case messagerecords.FieldErrorDetail:
+		v, ok := value.(string)
+		if !ok {
+			return fmt.Errorf("unexpected type %T for field %s", value, name)
+		}
+		m.SetErrorDetail(v)
+		return nil
+	case messagerecords.FieldSendTime:
+		v, ok := value.(time.Time)
+		if !ok {
+			return fmt.Errorf("unexpected type %T for field %s", value, name)
+		}
+		m.SetSendTime(v)
+		return nil
+	case messagerecords.FieldSourceType:
+		v, ok := value.(int)
+		if !ok {
+			return fmt.Errorf("unexpected type %T for field %s", value, name)
+		}
+		m.SetSourceType(v)
+		return nil
+	case messagerecords.FieldSourceID:
+		v, ok := value.(uint64)
+		if !ok {
+			return fmt.Errorf("unexpected type %T for field %s", value, name)
+		}
+		m.SetSourceID(v)
+		return nil
+	case messagerecords.FieldSubSourceID:
+		v, ok := value.(uint64)
+		if !ok {
+			return fmt.Errorf("unexpected type %T for field %s", value, name)
+		}
+		m.SetSubSourceID(v)
+		return nil
+	}
+	return fmt.Errorf("unknown MessageRecords field %s", name)
+}
+
+// AddedFields returns all numeric fields that were incremented/decremented during
+// this mutation.
+func (m *MessageRecordsMutation) AddedFields() []string {
+	var fields []string
+	if m.addstatus != nil {
+		fields = append(fields, messagerecords.FieldStatus)
+	}
+	if m.addcontact_id != nil {
+		fields = append(fields, messagerecords.FieldContactID)
+	}
+	if m.addcontact_type != nil {
+		fields = append(fields, messagerecords.FieldContactType)
+	}
+	if m.addcontent_type != nil {
+		fields = append(fields, messagerecords.FieldContentType)
+	}
+	if m.addsource_type != nil {
+		fields = append(fields, messagerecords.FieldSourceType)
+	}
+	if m.addsource_id != nil {
+		fields = append(fields, messagerecords.FieldSourceID)
+	}
+	if m.addsub_source_id != nil {
+		fields = append(fields, messagerecords.FieldSubSourceID)
+	}
+	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 *MessageRecordsMutation) AddedField(name string) (ent.Value, bool) {
+	switch name {
+	case messagerecords.FieldStatus:
+		return m.AddedStatus()
+	case messagerecords.FieldContactID:
+		return m.AddedContactID()
+	case messagerecords.FieldContactType:
+		return m.AddedContactType()
+	case messagerecords.FieldContentType:
+		return m.AddedContentType()
+	case messagerecords.FieldSourceType:
+		return m.AddedSourceType()
+	case messagerecords.FieldSourceID:
+		return m.AddedSourceID()
+	case messagerecords.FieldSubSourceID:
+		return m.AddedSubSourceID()
+	}
+	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 *MessageRecordsMutation) AddField(name string, value ent.Value) error {
+	switch name {
+	case messagerecords.FieldStatus:
+		v, ok := value.(int8)
+		if !ok {
+			return fmt.Errorf("unexpected type %T for field %s", value, name)
+		}
+		m.AddStatus(v)
+		return nil
+	case messagerecords.FieldContactID:
+		v, ok := value.(int64)
+		if !ok {
+			return fmt.Errorf("unexpected type %T for field %s", value, name)
+		}
+		m.AddContactID(v)
+		return nil
+	case messagerecords.FieldContactType:
+		v, ok := value.(int)
+		if !ok {
+			return fmt.Errorf("unexpected type %T for field %s", value, name)
+		}
+		m.AddContactType(v)
+		return nil
+	case messagerecords.FieldContentType:
+		v, ok := value.(int)
+		if !ok {
+			return fmt.Errorf("unexpected type %T for field %s", value, name)
+		}
+		m.AddContentType(v)
+		return nil
+	case messagerecords.FieldSourceType:
+		v, ok := value.(int)
+		if !ok {
+			return fmt.Errorf("unexpected type %T for field %s", value, name)
+		}
+		m.AddSourceType(v)
+		return nil
+	case messagerecords.FieldSourceID:
+		v, ok := value.(int64)
+		if !ok {
+			return fmt.Errorf("unexpected type %T for field %s", value, name)
+		}
+		m.AddSourceID(v)
+		return nil
+	case messagerecords.FieldSubSourceID:
+		v, ok := value.(int64)
+		if !ok {
+			return fmt.Errorf("unexpected type %T for field %s", value, name)
+		}
+		m.AddSubSourceID(v)
+		return nil
+	}
+	return fmt.Errorf("unknown MessageRecords numeric field %s", name)
+}
+
+// ClearedFields returns all nullable fields that were cleared during this
+// mutation.
+func (m *MessageRecordsMutation) ClearedFields() []string {
+	var fields []string
+	if m.FieldCleared(messagerecords.FieldStatus) {
+		fields = append(fields, messagerecords.FieldStatus)
+	}
+	if m.FieldCleared(messagerecords.FieldContactID) {
+		fields = append(fields, messagerecords.FieldContactID)
+	}
+	if m.FieldCleared(messagerecords.FieldSendTime) {
+		fields = append(fields, messagerecords.FieldSendTime)
+	}
+	if m.FieldCleared(messagerecords.FieldSourceID) {
+		fields = append(fields, messagerecords.FieldSourceID)
+	}
+	if m.FieldCleared(messagerecords.FieldSubSourceID) {
+		fields = append(fields, messagerecords.FieldSubSourceID)
+	}
+	return fields
+}
+
+// FieldCleared returns a boolean indicating if a field with the given name was
+// cleared in this mutation.
+func (m *MessageRecordsMutation) 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 *MessageRecordsMutation) ClearField(name string) error {
+	switch name {
+	case messagerecords.FieldStatus:
+		m.ClearStatus()
+		return nil
+	case messagerecords.FieldContactID:
+		m.ClearContactID()
+		return nil
+	case messagerecords.FieldSendTime:
+		m.ClearSendTime()
+		return nil
+	case messagerecords.FieldSourceID:
+		m.ClearSourceID()
+		return nil
+	case messagerecords.FieldSubSourceID:
+		m.ClearSubSourceID()
+		return nil
+	}
+	return fmt.Errorf("unknown MessageRecords 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 *MessageRecordsMutation) ResetField(name string) error {
+	switch name {
+	case messagerecords.FieldCreatedAt:
+		m.ResetCreatedAt()
+		return nil
+	case messagerecords.FieldUpdatedAt:
+		m.ResetUpdatedAt()
+		return nil
+	case messagerecords.FieldStatus:
+		m.ResetStatus()
+		return nil
+	case messagerecords.FieldBotWxid:
+		m.ResetBotWxid()
+		return nil
+	case messagerecords.FieldContactID:
+		m.ResetContactID()
+		return nil
+	case messagerecords.FieldContactType:
+		m.ResetContactType()
+		return nil
+	case messagerecords.FieldContactWxid:
+		m.ResetContactWxid()
+		return nil
+	case messagerecords.FieldContentType:
+		m.ResetContentType()
+		return nil
+	case messagerecords.FieldContent:
+		m.ResetContent()
+		return nil
+	case messagerecords.FieldErrorDetail:
+		m.ResetErrorDetail()
+		return nil
+	case messagerecords.FieldSendTime:
+		m.ResetSendTime()
+		return nil
+	case messagerecords.FieldSourceType:
+		m.ResetSourceType()
+		return nil
+	case messagerecords.FieldSourceID:
+		m.ResetSourceID()
+		return nil
+	case messagerecords.FieldSubSourceID:
+		m.ResetSubSourceID()
+		return nil
+	}
+	return fmt.Errorf("unknown MessageRecords field %s", name)
+}
+
+// AddedEdges returns all edge names that were set/added in this mutation.
+func (m *MessageRecordsMutation) 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 *MessageRecordsMutation) AddedIDs(name string) []ent.Value {
+	return nil
+}
+
+// RemovedEdges returns all edge names that were removed in this mutation.
+func (m *MessageRecordsMutation) 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 *MessageRecordsMutation) RemovedIDs(name string) []ent.Value {
+	return nil
+}
+
+// ClearedEdges returns all edge names that were cleared in this mutation.
+func (m *MessageRecordsMutation) 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 *MessageRecordsMutation) 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 *MessageRecordsMutation) ClearEdge(name string) error {
+	return fmt.Errorf("unknown MessageRecords 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 *MessageRecordsMutation) ResetEdge(name string) error {
+	return fmt.Errorf("unknown MessageRecords edge %s", name)
+}
+
 // TaskMutation represents an operation that mutates the Task nodes in the graph.
 type TaskMutation struct {
 	config

+ 80 - 0
ent/pagination.go

@@ -6,6 +6,7 @@ import (
 	"context"
 	"fmt"
 
+	"github.com/suyuan32/simple-admin-job/ent/messagerecords"
 	"github.com/suyuan32/simple-admin-job/ent/task"
 	"github.com/suyuan32/simple-admin-job/ent/tasklog"
 )
@@ -56,6 +57,85 @@ func (o OrderDirection) reverse() OrderDirection {
 
 const errInvalidPagination = "INVALID_PAGINATION"
 
+type MessageRecordsPager struct {
+	Order  messagerecords.OrderOption
+	Filter func(*MessageRecordsQuery) (*MessageRecordsQuery, error)
+}
+
+// MessageRecordsPaginateOption enables pagination customization.
+type MessageRecordsPaginateOption func(*MessageRecordsPager)
+
+// DefaultMessageRecordsOrder is the default ordering of MessageRecords.
+var DefaultMessageRecordsOrder = Desc(messagerecords.FieldID)
+
+func newMessageRecordsPager(opts []MessageRecordsPaginateOption) (*MessageRecordsPager, error) {
+	pager := &MessageRecordsPager{}
+	for _, opt := range opts {
+		opt(pager)
+	}
+	if pager.Order == nil {
+		pager.Order = DefaultMessageRecordsOrder
+	}
+	return pager, nil
+}
+
+func (p *MessageRecordsPager) ApplyFilter(query *MessageRecordsQuery) (*MessageRecordsQuery, error) {
+	if p.Filter != nil {
+		return p.Filter(query)
+	}
+	return query, nil
+}
+
+// MessageRecordsPageList is MessageRecords PageList result.
+type MessageRecordsPageList struct {
+	List        []*MessageRecords `json:"list"`
+	PageDetails *PageDetails      `json:"pageDetails"`
+}
+
+func (mr *MessageRecordsQuery) Page(
+	ctx context.Context, pageNum uint64, pageSize uint64, opts ...MessageRecordsPaginateOption,
+) (*MessageRecordsPageList, error) {
+
+	pager, err := newMessageRecordsPager(opts)
+	if err != nil {
+		return nil, err
+	}
+
+	if mr, err = pager.ApplyFilter(mr); err != nil {
+		return nil, err
+	}
+
+	ret := &MessageRecordsPageList{}
+
+	ret.PageDetails = &PageDetails{
+		Page: pageNum,
+		Size: pageSize,
+	}
+
+	count, err := mr.Clone().Count(ctx)
+
+	if err != nil {
+		return nil, err
+	}
+
+	ret.PageDetails.Total = uint64(count)
+
+	if pager.Order != nil {
+		mr = mr.Order(pager.Order)
+	} else {
+		mr = mr.Order(DefaultMessageRecordsOrder)
+	}
+
+	mr = mr.Offset(int((pageNum - 1) * pageSize)).Limit(int(pageSize))
+	list, err := mr.All(ctx)
+	if err != nil {
+		return nil, err
+	}
+	ret.List = list
+
+	return ret, nil
+}
+
 type TaskPager struct {
 	Order  task.OrderOption
 	Filter func(*TaskQuery) (*TaskQuery, error)

+ 3 - 0
ent/predicate/predicate.go

@@ -6,6 +6,9 @@ import (
 	"entgo.io/ent/dialect/sql"
 )
 
+// MessageRecords is the predicate function for messagerecords builders.
+type MessageRecords func(*sql.Selector)
+
 // Task is the predicate function for task builders.
 type Task func(*sql.Selector)
 

+ 54 - 0
ent/runtime.go

@@ -5,6 +5,7 @@ package ent
 import (
 	"time"
 
+	"github.com/suyuan32/simple-admin-job/ent/messagerecords"
 	"github.com/suyuan32/simple-admin-job/ent/schema"
 	"github.com/suyuan32/simple-admin-job/ent/task"
 	"github.com/suyuan32/simple-admin-job/ent/tasklog"
@@ -14,6 +15,59 @@ import (
 // (default values, validators, hooks and policies) and stitches it
 // to their package variables.
 func init() {
+	messagerecordsMixin := schema.MessageRecords{}.Mixin()
+	messagerecordsMixinFields0 := messagerecordsMixin[0].Fields()
+	_ = messagerecordsMixinFields0
+	messagerecordsMixinFields1 := messagerecordsMixin[1].Fields()
+	_ = messagerecordsMixinFields1
+	messagerecordsFields := schema.MessageRecords{}.Fields()
+	_ = messagerecordsFields
+	// messagerecordsDescCreatedAt is the schema descriptor for created_at field.
+	messagerecordsDescCreatedAt := messagerecordsMixinFields0[1].Descriptor()
+	// messagerecords.DefaultCreatedAt holds the default value on creation for the created_at field.
+	messagerecords.DefaultCreatedAt = messagerecordsDescCreatedAt.Default.(func() time.Time)
+	// messagerecordsDescUpdatedAt is the schema descriptor for updated_at field.
+	messagerecordsDescUpdatedAt := messagerecordsMixinFields0[2].Descriptor()
+	// messagerecords.DefaultUpdatedAt holds the default value on creation for the updated_at field.
+	messagerecords.DefaultUpdatedAt = messagerecordsDescUpdatedAt.Default.(func() time.Time)
+	// messagerecords.UpdateDefaultUpdatedAt holds the default value on update for the updated_at field.
+	messagerecords.UpdateDefaultUpdatedAt = messagerecordsDescUpdatedAt.UpdateDefault.(func() time.Time)
+	// messagerecordsDescStatus is the schema descriptor for status field.
+	messagerecordsDescStatus := messagerecordsMixinFields1[0].Descriptor()
+	// messagerecords.DefaultStatus holds the default value on creation for the status field.
+	messagerecords.DefaultStatus = messagerecordsDescStatus.Default.(uint8)
+	// messagerecordsDescContactType is the schema descriptor for contact_type field.
+	messagerecordsDescContactType := messagerecordsFields[2].Descriptor()
+	// messagerecords.DefaultContactType holds the default value on creation for the contact_type field.
+	messagerecords.DefaultContactType = messagerecordsDescContactType.Default.(int)
+	// messagerecordsDescContactWxid is the schema descriptor for contact_wxid field.
+	messagerecordsDescContactWxid := messagerecordsFields[3].Descriptor()
+	// messagerecords.DefaultContactWxid holds the default value on creation for the contact_wxid field.
+	messagerecords.DefaultContactWxid = messagerecordsDescContactWxid.Default.(string)
+	// messagerecordsDescContentType is the schema descriptor for content_type field.
+	messagerecordsDescContentType := messagerecordsFields[4].Descriptor()
+	// messagerecords.DefaultContentType holds the default value on creation for the content_type field.
+	messagerecords.DefaultContentType = messagerecordsDescContentType.Default.(int)
+	// messagerecordsDescContent is the schema descriptor for content field.
+	messagerecordsDescContent := messagerecordsFields[5].Descriptor()
+	// messagerecords.DefaultContent holds the default value on creation for the content field.
+	messagerecords.DefaultContent = messagerecordsDescContent.Default.(string)
+	// messagerecordsDescErrorDetail is the schema descriptor for error_detail field.
+	messagerecordsDescErrorDetail := messagerecordsFields[6].Descriptor()
+	// messagerecords.DefaultErrorDetail holds the default value on creation for the error_detail field.
+	messagerecords.DefaultErrorDetail = messagerecordsDescErrorDetail.Default.(string)
+	// messagerecordsDescSourceType is the schema descriptor for source_type field.
+	messagerecordsDescSourceType := messagerecordsFields[8].Descriptor()
+	// messagerecords.DefaultSourceType holds the default value on creation for the source_type field.
+	messagerecords.DefaultSourceType = messagerecordsDescSourceType.Default.(int)
+	// messagerecordsDescSourceID is the schema descriptor for source_id field.
+	messagerecordsDescSourceID := messagerecordsFields[9].Descriptor()
+	// messagerecords.DefaultSourceID holds the default value on creation for the source_id field.
+	messagerecords.DefaultSourceID = messagerecordsDescSourceID.Default.(uint64)
+	// messagerecordsDescSubSourceID is the schema descriptor for sub_source_id field.
+	messagerecordsDescSubSourceID := messagerecordsFields[10].Descriptor()
+	// messagerecords.DefaultSubSourceID holds the default value on creation for the sub_source_id field.
+	messagerecords.DefaultSubSourceID = messagerecordsDescSubSourceID.Default.(uint64)
 	taskMixin := schema.Task{}.Mixin()
 	taskMixinFields0 := taskMixin[0].Fields()
 	_ = taskMixinFields0

+ 70 - 0
ent/schema/message_records.go

@@ -0,0 +1,70 @@
+package schema
+
+import (
+	"entgo.io/ent"
+	"entgo.io/ent/dialect/entsql"
+	"entgo.io/ent/schema"
+	"entgo.io/ent/schema/field"
+	"github.com/suyuan32/simple-admin-common/orm/ent/mixins"
+)
+
+type MessageRecords struct {
+	ent.Schema
+}
+
+func (MessageRecords) Fields() []ent.Field {
+	return []ent.Field{
+		field.String("bot_wxid").
+			Annotations(entsql.WithComments(true)).
+			Comment("机器人微信 id"),
+		field.Uint64("contact_id").Optional().
+			Annotations(entsql.WithComments(true)).
+			Comment("联系人 id"),
+		field.Int("contact_type").Default(1).
+			Annotations(entsql.WithComments(true)).
+			Comment("类型:1好友,2群组,3企业微信联系人"),
+		field.String("contact_wxid").Default("").
+			Annotations(entsql.WithComments(true)).
+			Comment("接收方微信 id"),
+		field.Int("content_type").Default(1).
+			Annotations(entsql.WithComments(true)).
+			Comment("内容类型 1 文本 2 文件"),
+		field.String("content").Default("").
+			Annotations(entsql.WithComments(true)).
+			Comment("发送内容"),
+		field.String("error_detail").Default("").
+			Annotations(entsql.WithComments(true)).
+			Comment("异常原因"),
+		field.Time("send_time").Optional().
+			Annotations(entsql.WithComments(true)).
+			Comment("发送时间"),
+		field.Int("source_type").Default(1).
+			Annotations(entsql.WithComments(true)).
+			Comment("源类型 1 点发 2 群发 3 SOP"),
+		field.Uint64("source_id").Default(1).Optional().
+			Annotations(entsql.WithComments(true)).
+			Comment("源 ID"),
+		field.Uint64("sub_source_id").Default(1).Optional().
+			Annotations(entsql.WithComments(true)).
+			Comment("次源 ID"),
+	}
+}
+
+func (MessageRecords) Mixin() []ent.Mixin {
+	return []ent.Mixin{
+		mixins.IDMixin{},
+		mixins.StatusMixin{},
+	}
+}
+
+func (MessageRecords) Indexes() []ent.Index {
+	return nil
+}
+
+func (MessageRecords) Edges() []ent.Edge {
+	return nil
+}
+
+func (MessageRecords) Annotations() []schema.Annotation {
+	return []schema.Annotation{entsql.Annotation{Table: "message_records"}}
+}

+ 312 - 0
ent/set_not_nil.go

@@ -5,6 +5,318 @@ package ent
 import "time"
 
 // set field if value's pointer is not nil.
+func (mr *MessageRecordsUpdate) SetNotNilUpdatedAt(value *time.Time) *MessageRecordsUpdate {
+	if value != nil {
+		return mr.SetUpdatedAt(*value)
+	}
+	return mr
+}
+
+// set field if value's pointer is not nil.
+func (mr *MessageRecordsUpdateOne) SetNotNilUpdatedAt(value *time.Time) *MessageRecordsUpdateOne {
+	if value != nil {
+		return mr.SetUpdatedAt(*value)
+	}
+	return mr
+}
+
+// set field if value's pointer is not nil.
+func (mr *MessageRecordsCreate) SetNotNilUpdatedAt(value *time.Time) *MessageRecordsCreate {
+	if value != nil {
+		return mr.SetUpdatedAt(*value)
+	}
+	return mr
+}
+
+// set field if value's pointer is not nil.
+func (mr *MessageRecordsUpdate) SetNotNilStatus(value *uint8) *MessageRecordsUpdate {
+	if value != nil {
+		return mr.SetStatus(*value)
+	}
+	return mr
+}
+
+// set field if value's pointer is not nil.
+func (mr *MessageRecordsUpdateOne) SetNotNilStatus(value *uint8) *MessageRecordsUpdateOne {
+	if value != nil {
+		return mr.SetStatus(*value)
+	}
+	return mr
+}
+
+// set field if value's pointer is not nil.
+func (mr *MessageRecordsCreate) SetNotNilStatus(value *uint8) *MessageRecordsCreate {
+	if value != nil {
+		return mr.SetStatus(*value)
+	}
+	return mr
+}
+
+// set field if value's pointer is not nil.
+func (mr *MessageRecordsUpdate) SetNotNilBotWxid(value *string) *MessageRecordsUpdate {
+	if value != nil {
+		return mr.SetBotWxid(*value)
+	}
+	return mr
+}
+
+// set field if value's pointer is not nil.
+func (mr *MessageRecordsUpdateOne) SetNotNilBotWxid(value *string) *MessageRecordsUpdateOne {
+	if value != nil {
+		return mr.SetBotWxid(*value)
+	}
+	return mr
+}
+
+// set field if value's pointer is not nil.
+func (mr *MessageRecordsCreate) SetNotNilBotWxid(value *string) *MessageRecordsCreate {
+	if value != nil {
+		return mr.SetBotWxid(*value)
+	}
+	return mr
+}
+
+// set field if value's pointer is not nil.
+func (mr *MessageRecordsUpdate) SetNotNilContactID(value *uint64) *MessageRecordsUpdate {
+	if value != nil {
+		return mr.SetContactID(*value)
+	}
+	return mr
+}
+
+// set field if value's pointer is not nil.
+func (mr *MessageRecordsUpdateOne) SetNotNilContactID(value *uint64) *MessageRecordsUpdateOne {
+	if value != nil {
+		return mr.SetContactID(*value)
+	}
+	return mr
+}
+
+// set field if value's pointer is not nil.
+func (mr *MessageRecordsCreate) SetNotNilContactID(value *uint64) *MessageRecordsCreate {
+	if value != nil {
+		return mr.SetContactID(*value)
+	}
+	return mr
+}
+
+// set field if value's pointer is not nil.
+func (mr *MessageRecordsUpdate) SetNotNilContactType(value *int) *MessageRecordsUpdate {
+	if value != nil {
+		return mr.SetContactType(*value)
+	}
+	return mr
+}
+
+// set field if value's pointer is not nil.
+func (mr *MessageRecordsUpdateOne) SetNotNilContactType(value *int) *MessageRecordsUpdateOne {
+	if value != nil {
+		return mr.SetContactType(*value)
+	}
+	return mr
+}
+
+// set field if value's pointer is not nil.
+func (mr *MessageRecordsCreate) SetNotNilContactType(value *int) *MessageRecordsCreate {
+	if value != nil {
+		return mr.SetContactType(*value)
+	}
+	return mr
+}
+
+// set field if value's pointer is not nil.
+func (mr *MessageRecordsUpdate) SetNotNilContactWxid(value *string) *MessageRecordsUpdate {
+	if value != nil {
+		return mr.SetContactWxid(*value)
+	}
+	return mr
+}
+
+// set field if value's pointer is not nil.
+func (mr *MessageRecordsUpdateOne) SetNotNilContactWxid(value *string) *MessageRecordsUpdateOne {
+	if value != nil {
+		return mr.SetContactWxid(*value)
+	}
+	return mr
+}
+
+// set field if value's pointer is not nil.
+func (mr *MessageRecordsCreate) SetNotNilContactWxid(value *string) *MessageRecordsCreate {
+	if value != nil {
+		return mr.SetContactWxid(*value)
+	}
+	return mr
+}
+
+// set field if value's pointer is not nil.
+func (mr *MessageRecordsUpdate) SetNotNilContentType(value *int) *MessageRecordsUpdate {
+	if value != nil {
+		return mr.SetContentType(*value)
+	}
+	return mr
+}
+
+// set field if value's pointer is not nil.
+func (mr *MessageRecordsUpdateOne) SetNotNilContentType(value *int) *MessageRecordsUpdateOne {
+	if value != nil {
+		return mr.SetContentType(*value)
+	}
+	return mr
+}
+
+// set field if value's pointer is not nil.
+func (mr *MessageRecordsCreate) SetNotNilContentType(value *int) *MessageRecordsCreate {
+	if value != nil {
+		return mr.SetContentType(*value)
+	}
+	return mr
+}
+
+// set field if value's pointer is not nil.
+func (mr *MessageRecordsUpdate) SetNotNilContent(value *string) *MessageRecordsUpdate {
+	if value != nil {
+		return mr.SetContent(*value)
+	}
+	return mr
+}
+
+// set field if value's pointer is not nil.
+func (mr *MessageRecordsUpdateOne) SetNotNilContent(value *string) *MessageRecordsUpdateOne {
+	if value != nil {
+		return mr.SetContent(*value)
+	}
+	return mr
+}
+
+// set field if value's pointer is not nil.
+func (mr *MessageRecordsCreate) SetNotNilContent(value *string) *MessageRecordsCreate {
+	if value != nil {
+		return mr.SetContent(*value)
+	}
+	return mr
+}
+
+// set field if value's pointer is not nil.
+func (mr *MessageRecordsUpdate) SetNotNilErrorDetail(value *string) *MessageRecordsUpdate {
+	if value != nil {
+		return mr.SetErrorDetail(*value)
+	}
+	return mr
+}
+
+// set field if value's pointer is not nil.
+func (mr *MessageRecordsUpdateOne) SetNotNilErrorDetail(value *string) *MessageRecordsUpdateOne {
+	if value != nil {
+		return mr.SetErrorDetail(*value)
+	}
+	return mr
+}
+
+// set field if value's pointer is not nil.
+func (mr *MessageRecordsCreate) SetNotNilErrorDetail(value *string) *MessageRecordsCreate {
+	if value != nil {
+		return mr.SetErrorDetail(*value)
+	}
+	return mr
+}
+
+// set field if value's pointer is not nil.
+func (mr *MessageRecordsUpdate) SetNotNilSendTime(value *time.Time) *MessageRecordsUpdate {
+	if value != nil {
+		return mr.SetSendTime(*value)
+	}
+	return mr
+}
+
+// set field if value's pointer is not nil.
+func (mr *MessageRecordsUpdateOne) SetNotNilSendTime(value *time.Time) *MessageRecordsUpdateOne {
+	if value != nil {
+		return mr.SetSendTime(*value)
+	}
+	return mr
+}
+
+// set field if value's pointer is not nil.
+func (mr *MessageRecordsCreate) SetNotNilSendTime(value *time.Time) *MessageRecordsCreate {
+	if value != nil {
+		return mr.SetSendTime(*value)
+	}
+	return mr
+}
+
+// set field if value's pointer is not nil.
+func (mr *MessageRecordsUpdate) SetNotNilSourceType(value *int) *MessageRecordsUpdate {
+	if value != nil {
+		return mr.SetSourceType(*value)
+	}
+	return mr
+}
+
+// set field if value's pointer is not nil.
+func (mr *MessageRecordsUpdateOne) SetNotNilSourceType(value *int) *MessageRecordsUpdateOne {
+	if value != nil {
+		return mr.SetSourceType(*value)
+	}
+	return mr
+}
+
+// set field if value's pointer is not nil.
+func (mr *MessageRecordsCreate) SetNotNilSourceType(value *int) *MessageRecordsCreate {
+	if value != nil {
+		return mr.SetSourceType(*value)
+	}
+	return mr
+}
+
+// set field if value's pointer is not nil.
+func (mr *MessageRecordsUpdate) SetNotNilSourceID(value *uint64) *MessageRecordsUpdate {
+	if value != nil {
+		return mr.SetSourceID(*value)
+	}
+	return mr
+}
+
+// set field if value's pointer is not nil.
+func (mr *MessageRecordsUpdateOne) SetNotNilSourceID(value *uint64) *MessageRecordsUpdateOne {
+	if value != nil {
+		return mr.SetSourceID(*value)
+	}
+	return mr
+}
+
+// set field if value's pointer is not nil.
+func (mr *MessageRecordsCreate) SetNotNilSourceID(value *uint64) *MessageRecordsCreate {
+	if value != nil {
+		return mr.SetSourceID(*value)
+	}
+	return mr
+}
+
+// set field if value's pointer is not nil.
+func (mr *MessageRecordsUpdate) SetNotNilSubSourceID(value *uint64) *MessageRecordsUpdate {
+	if value != nil {
+		return mr.SetSubSourceID(*value)
+	}
+	return mr
+}
+
+// set field if value's pointer is not nil.
+func (mr *MessageRecordsUpdateOne) SetNotNilSubSourceID(value *uint64) *MessageRecordsUpdateOne {
+	if value != nil {
+		return mr.SetSubSourceID(*value)
+	}
+	return mr
+}
+
+// set field if value's pointer is not nil.
+func (mr *MessageRecordsCreate) SetNotNilSubSourceID(value *uint64) *MessageRecordsCreate {
+	if value != nil {
+		return mr.SetSubSourceID(*value)
+	}
+	return mr
+}
+
+// set field if value's pointer is not nil.
 func (t *TaskUpdate) SetNotNilUpdatedAt(value *time.Time) *TaskUpdate {
 	if value != nil {
 		return t.SetUpdatedAt(*value)

+ 4 - 1
ent/tx.go

@@ -14,6 +14,8 @@ import (
 // Tx is a transactional client that is created by calling Client.Tx().
 type Tx struct {
 	config
+	// MessageRecords is the client for interacting with the MessageRecords builders.
+	MessageRecords *MessageRecordsClient
 	// Task is the client for interacting with the Task builders.
 	Task *TaskClient
 	// TaskLog is the client for interacting with the TaskLog builders.
@@ -149,6 +151,7 @@ func (tx *Tx) Client() *Client {
 }
 
 func (tx *Tx) init() {
+	tx.MessageRecords = NewMessageRecordsClient(tx.config)
 	tx.Task = NewTaskClient(tx.config)
 	tx.TaskLog = NewTaskLogClient(tx.config)
 }
@@ -160,7 +163,7 @@ func (tx *Tx) init() {
 // of them in order to commit or rollback the transaction.
 //
 // If a closed transaction is embedded in one of the generated entities, and the entity
-// applies a query, for example: Task.QueryXXX(), the query will be executed
+// applies a query, for example: MessageRecords.QueryXXX(), the query will be executed
 // through the driver which created this transaction.
 //
 // Note that txDriver is not goroutine safe.

+ 5 - 4
internal/config/config.go

@@ -9,10 +9,11 @@ import (
 
 type Config struct {
 	zrpc.RpcServerConf
-	DatabaseConf config.DatabaseConf
-	RedisConf    config.RedisConf
-	AsynqConf    asynq.AsynqConf
-	TaskConf     TaskConf
+	DatabaseConf   config.DatabaseConf
+	WXDatabaseConf config.DatabaseConf
+	RedisConf      config.RedisConf
+	AsynqConf      asynq.AsynqConf
+	TaskConf       TaskConf
 }
 
 type TaskConf struct {

+ 134 - 0
internal/mqs/amq/handler/amq/wxhook/send_wx.go

@@ -0,0 +1,134 @@
+package wxhook
+
+import (
+	"context"
+	"encoding/json"
+	"errors"
+	"fmt"
+	"github.com/imroc/req/v3"
+	"github.com/suyuan32/simple-admin-common/i18n"
+	"github.com/suyuan32/simple-admin-job/ent"
+	"github.com/suyuan32/simple-admin-job/ent/messagerecords"
+	"github.com/suyuan32/simple-admin-job/ent/task"
+	"github.com/suyuan32/simple-admin-job/internal/enum/taskresult"
+	"github.com/suyuan32/simple-admin-job/internal/mqs/amq/types/pattern"
+	"github.com/suyuan32/simple-admin-job/internal/utils/dberrorhandler"
+	"github.com/zeromicro/go-zero/core/errorx"
+	"github.com/zeromicro/go-zero/core/logx"
+	"time"
+
+	"github.com/hibiken/asynq"
+
+	"github.com/suyuan32/simple-admin-job/internal/mqs/amq/types/payload"
+	"github.com/suyuan32/simple-admin-job/internal/svc"
+)
+
+type SendWxHandler struct {
+	svcCtx *svc.ServiceContext
+	taskId uint64
+}
+
+func NewSendWxHandler(svcCtx *svc.ServiceContext) *SendWxHandler {
+	task, err := svcCtx.DB.Task.Query().Where(task.PatternEQ(pattern.RecordSendWx)).First(context.Background())
+	if err != nil || task == nil {
+		return nil
+	}
+
+	return &SendWxHandler{
+		svcCtx: svcCtx,
+		taskId: task.ID,
+	}
+}
+
+// ProcessTask if return err != nil , asynq will retry | 如果返回错误不为空则会重试
+func (l *SendWxHandler) ProcessTask(ctx context.Context, t *asynq.Task) error {
+	if l.taskId == 0 {
+		logx.Errorw("failed to load task info")
+		return errorx.NewInternalError(i18n.DatabaseError)
+	}
+
+	var p payload.SendWxPayload
+	if err := json.Unmarshal(t.Payload(), &p); err != nil {
+		return errors.Join(err, fmt.Errorf("failed to umarshal the payload :%s", string(t.Payload())))
+	}
+
+	// 更新最旧的 p.Number 条 status 值为 1 或 4 的 message_records 记录的 status 为 2
+	messages, err := l.svcCtx.WX_DB.MessageRecords.Query().
+		Where(messagerecords.StatusIn(1, 4)).
+		Order(ent.Asc(messagerecords.FieldCreatedAt)).
+		Limit(p.Number).
+		All(ctx)
+	for _, m := range messages {
+		_, err := l.svcCtx.WX_DB.MessageRecords.UpdateOneID(m.ID).SetStatus(2).Save(ctx)
+		if err != nil {
+			// 处理错误
+		}
+	}
+
+	startTime := time.Now()
+
+	client := req.C().DevMode()
+	client.SetCommonRetryCount(2).
+		SetCommonRetryBackoffInterval(1*time.Second, 5*time.Second).
+		SetCommonRetryFixedInterval(2 * time.Second).SetTimeout(30 * time.Second)
+
+	type SendTextMsgReq struct {
+		Wxid string `json:"wxid"`
+		Msg  string `json:"msg"`
+	}
+
+	type SendFileMsgReq struct {
+		Wxid        string `json:"wxid"`
+		Filepath    string `json:"filepath"`
+		Diyfilename string `json:"diyfilename"`
+	}
+
+	// 遍历 p.WxList 发送消息将其转换为字段,key 为 Wxid,value 为 Port
+	wxidPortMap := make(map[string]string)
+	for _, wx := range p.WxList {
+		wxidPortMap[wx.Wxid] = wx.Port
+	}
+
+	for _, v := range messages {
+		wxPort := wxidPortMap[v.BotWxid]
+		if v.ContentType == 1 {
+			_, err = client.R().SetBody(&SendTextMsgReq{
+				Wxid: v.ContactWxid,
+				Msg:  v.Content,
+			}).Post("http://" + p.Ip + ":" + wxPort + "/SendTextMsg")
+		} else {
+			_, err = client.R().SetBody(&SendFileMsgReq{
+				Wxid:     v.ContactWxid,
+				Filepath: v.Content,
+			}).Post("http://" + p.Ip + ":" + wxPort + "/SendTextMsg")
+		}
+
+		if err != nil {
+			_, err := l.svcCtx.WX_DB.MessageRecords.UpdateOneID(v.ID).SetStatus(4).Save(ctx)
+			if err != nil {
+				// 处理错误
+			}
+		} else {
+			_, err := l.svcCtx.WX_DB.MessageRecords.UpdateOneID(v.ID).SetStatus(3).Save(ctx)
+			if err != nil {
+				// 处理错误
+			}
+		}
+	}
+
+	finishTime := time.Now()
+
+	err = l.svcCtx.DB.TaskLog.Create().
+		SetStartedAt(startTime).
+		SetFinishedAt(finishTime).
+		SetResult(taskresult.Success).
+		SetTasksID(l.taskId).
+		Exec(context.Background())
+
+	if err != nil {
+		return dberrorhandler.DefaultEntError(logx.WithContext(context.Background()), err,
+			"failed to save task log to database")
+	}
+
+	return nil
+}

+ 2 - 0
internal/mqs/amq/task/mqtask/register.go

@@ -17,5 +17,7 @@ func (m *MQTask) Register() {
 
 	mux.Handle(pattern.RecordSayMorning, wxhook.NewSayMorningHandler(m.svcCtx))
 
+	mux.Handle(pattern.RecordSendWx, wxhook.NewSendWxHandler(m.svcCtx))
+
 	m.mux = mux
 }

+ 1 - 0
internal/mqs/amq/types/pattern/pattern.go

@@ -3,3 +3,4 @@ package pattern
 
 const RecordHelloWorld = "hello_world"
 const RecordSayMorning = "say_morning"
+const RecordSendWx = "send_wx"

+ 12 - 0
internal/mqs/amq/types/payload/payload.go

@@ -12,3 +12,15 @@ type SayMorningPayload struct {
 	Nickname string `json:"nickname"`
 	Msg      string `json:"msg"`
 }
+
+type SendWxPayload struct {
+	Ip     string   `json:"ip"`
+	Number int      `json:"number"`
+	WxList []WxList `json:"wx_list"`
+}
+
+type WxList struct {
+	Port     string `json:"port"`
+	Wxid     string `json:"wxid"`
+	Nickname string `json:"nickname"`
+}

+ 8 - 0
internal/svc/service_context.go

@@ -27,6 +27,7 @@ import (
 type ServiceContext struct {
 	Config         config.Config
 	DB             *ent.Client
+	WX_DB          *ent.Client
 	Redis          redis.UniversalClient
 	AsynqServer    *asynq.Server
 	AsynqScheduler *asynq.Scheduler
@@ -40,9 +41,16 @@ func NewServiceContext(c config.Config) *ServiceContext {
 		ent.Debug(), // debug mode
 	)
 
+	wxdb := ent.NewClient(
+		ent.Log(logx.Info), // logger
+		ent.Driver(c.WXDatabaseConf.NewNoCacheDriver()),
+		ent.Debug(), // debug mode
+	)
+
 	return &ServiceContext{
 		Config:         c,
 		DB:             db,
+		WX_DB:          wxdb,
 		AsynqServer:    c.AsynqConf.WithOriginalRedisConf(c.RedisConf).NewServer(),
 		AsynqScheduler: c.AsynqConf.NewScheduler(),
 		AsynqPTM:       c.AsynqConf.NewPeriodicTaskManager(periodicconfig.NewEntConfigProvider(db)),