Explorar el Código

增加batch_msg表,用于批量发送

DESKTOP-53URE31\USER hace 8 meses
padre
commit
626df99143

+ 238 - 0
ent/batchmsg.go

@@ -0,0 +1,238 @@
+// Code generated by ent, DO NOT EDIT.
+
+package ent
+
+import (
+	"fmt"
+	"strings"
+	"time"
+	"wechat-api/ent/batchmsg"
+
+	"entgo.io/ent"
+	"entgo.io/ent/dialect/sql"
+)
+
+// BatchMsg is the model entity for the BatchMsg schema.
+type BatchMsg 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"`
+	// Delete Time | 删除日期
+	DeletedAt time.Time `json:"deleted_at,omitempty"`
+	// 状态 0 未开始 1 开始发送 2 发送完成 3 发送中止
+	Status uint8 `json:"status,omitempty"`
+	// 批次号
+	BatchNo string `json:"batch_no,omitempty"`
+	// 发送方微信ID
+	Fromwxid string `json:"fromwxid,omitempty"`
+	// 内容
+	Msg string `json:"msg,omitempty"`
+	// 发送规则 all 全部 tag1,tag2 按tag发送
+	Tag string `json:"tag,omitempty"`
+	// 总数
+	Total int32 `json:"total,omitempty"`
+	// 成功数量
+	Success int32 `json:"success,omitempty"`
+	// 失败数量
+	Fail int32 `json:"fail,omitempty"`
+	// 开始时间
+	StartTime time.Time `json:"start_time,omitempty"`
+	// 结束时间
+	StopTime     time.Time `json:"stop_time,omitempty"`
+	selectValues sql.SelectValues
+}
+
+// scanValues returns the types for scanning values from sql.Rows.
+func (*BatchMsg) scanValues(columns []string) ([]any, error) {
+	values := make([]any, len(columns))
+	for i := range columns {
+		switch columns[i] {
+		case batchmsg.FieldID, batchmsg.FieldStatus, batchmsg.FieldTotal, batchmsg.FieldSuccess, batchmsg.FieldFail:
+			values[i] = new(sql.NullInt64)
+		case batchmsg.FieldBatchNo, batchmsg.FieldFromwxid, batchmsg.FieldMsg, batchmsg.FieldTag:
+			values[i] = new(sql.NullString)
+		case batchmsg.FieldCreatedAt, batchmsg.FieldUpdatedAt, batchmsg.FieldDeletedAt, batchmsg.FieldStartTime, batchmsg.FieldStopTime:
+			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 BatchMsg fields.
+func (bm *BatchMsg) 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 batchmsg.FieldID:
+			value, ok := values[i].(*sql.NullInt64)
+			if !ok {
+				return fmt.Errorf("unexpected type %T for field id", value)
+			}
+			bm.ID = uint64(value.Int64)
+		case batchmsg.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 {
+				bm.CreatedAt = value.Time
+			}
+		case batchmsg.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 {
+				bm.UpdatedAt = value.Time
+			}
+		case batchmsg.FieldDeletedAt:
+			if value, ok := values[i].(*sql.NullTime); !ok {
+				return fmt.Errorf("unexpected type %T for field deleted_at", values[i])
+			} else if value.Valid {
+				bm.DeletedAt = value.Time
+			}
+		case batchmsg.FieldStatus:
+			if value, ok := values[i].(*sql.NullInt64); !ok {
+				return fmt.Errorf("unexpected type %T for field status", values[i])
+			} else if value.Valid {
+				bm.Status = uint8(value.Int64)
+			}
+		case batchmsg.FieldBatchNo:
+			if value, ok := values[i].(*sql.NullString); !ok {
+				return fmt.Errorf("unexpected type %T for field batch_no", values[i])
+			} else if value.Valid {
+				bm.BatchNo = value.String
+			}
+		case batchmsg.FieldFromwxid:
+			if value, ok := values[i].(*sql.NullString); !ok {
+				return fmt.Errorf("unexpected type %T for field fromwxid", values[i])
+			} else if value.Valid {
+				bm.Fromwxid = value.String
+			}
+		case batchmsg.FieldMsg:
+			if value, ok := values[i].(*sql.NullString); !ok {
+				return fmt.Errorf("unexpected type %T for field msg", values[i])
+			} else if value.Valid {
+				bm.Msg = value.String
+			}
+		case batchmsg.FieldTag:
+			if value, ok := values[i].(*sql.NullString); !ok {
+				return fmt.Errorf("unexpected type %T for field tag", values[i])
+			} else if value.Valid {
+				bm.Tag = value.String
+			}
+		case batchmsg.FieldTotal:
+			if value, ok := values[i].(*sql.NullInt64); !ok {
+				return fmt.Errorf("unexpected type %T for field total", values[i])
+			} else if value.Valid {
+				bm.Total = int32(value.Int64)
+			}
+		case batchmsg.FieldSuccess:
+			if value, ok := values[i].(*sql.NullInt64); !ok {
+				return fmt.Errorf("unexpected type %T for field success", values[i])
+			} else if value.Valid {
+				bm.Success = int32(value.Int64)
+			}
+		case batchmsg.FieldFail:
+			if value, ok := values[i].(*sql.NullInt64); !ok {
+				return fmt.Errorf("unexpected type %T for field fail", values[i])
+			} else if value.Valid {
+				bm.Fail = int32(value.Int64)
+			}
+		case batchmsg.FieldStartTime:
+			if value, ok := values[i].(*sql.NullTime); !ok {
+				return fmt.Errorf("unexpected type %T for field start_time", values[i])
+			} else if value.Valid {
+				bm.StartTime = value.Time
+			}
+		case batchmsg.FieldStopTime:
+			if value, ok := values[i].(*sql.NullTime); !ok {
+				return fmt.Errorf("unexpected type %T for field stop_time", values[i])
+			} else if value.Valid {
+				bm.StopTime = value.Time
+			}
+		default:
+			bm.selectValues.Set(columns[i], values[i])
+		}
+	}
+	return nil
+}
+
+// Value returns the ent.Value that was dynamically selected and assigned to the BatchMsg.
+// This includes values selected through modifiers, order, etc.
+func (bm *BatchMsg) Value(name string) (ent.Value, error) {
+	return bm.selectValues.Get(name)
+}
+
+// Update returns a builder for updating this BatchMsg.
+// Note that you need to call BatchMsg.Unwrap() before calling this method if this BatchMsg
+// was returned from a transaction, and the transaction was committed or rolled back.
+func (bm *BatchMsg) Update() *BatchMsgUpdateOne {
+	return NewBatchMsgClient(bm.config).UpdateOne(bm)
+}
+
+// Unwrap unwraps the BatchMsg 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 (bm *BatchMsg) Unwrap() *BatchMsg {
+	_tx, ok := bm.config.driver.(*txDriver)
+	if !ok {
+		panic("ent: BatchMsg is not a transactional entity")
+	}
+	bm.config.driver = _tx.drv
+	return bm
+}
+
+// String implements the fmt.Stringer.
+func (bm *BatchMsg) String() string {
+	var builder strings.Builder
+	builder.WriteString("BatchMsg(")
+	builder.WriteString(fmt.Sprintf("id=%v, ", bm.ID))
+	builder.WriteString("created_at=")
+	builder.WriteString(bm.CreatedAt.Format(time.ANSIC))
+	builder.WriteString(", ")
+	builder.WriteString("updated_at=")
+	builder.WriteString(bm.UpdatedAt.Format(time.ANSIC))
+	builder.WriteString(", ")
+	builder.WriteString("deleted_at=")
+	builder.WriteString(bm.DeletedAt.Format(time.ANSIC))
+	builder.WriteString(", ")
+	builder.WriteString("status=")
+	builder.WriteString(fmt.Sprintf("%v", bm.Status))
+	builder.WriteString(", ")
+	builder.WriteString("batch_no=")
+	builder.WriteString(bm.BatchNo)
+	builder.WriteString(", ")
+	builder.WriteString("fromwxid=")
+	builder.WriteString(bm.Fromwxid)
+	builder.WriteString(", ")
+	builder.WriteString("msg=")
+	builder.WriteString(bm.Msg)
+	builder.WriteString(", ")
+	builder.WriteString("tag=")
+	builder.WriteString(bm.Tag)
+	builder.WriteString(", ")
+	builder.WriteString("total=")
+	builder.WriteString(fmt.Sprintf("%v", bm.Total))
+	builder.WriteString(", ")
+	builder.WriteString("success=")
+	builder.WriteString(fmt.Sprintf("%v", bm.Success))
+	builder.WriteString(", ")
+	builder.WriteString("fail=")
+	builder.WriteString(fmt.Sprintf("%v", bm.Fail))
+	builder.WriteString(", ")
+	builder.WriteString("start_time=")
+	builder.WriteString(bm.StartTime.Format(time.ANSIC))
+	builder.WriteString(", ")
+	builder.WriteString("stop_time=")
+	builder.WriteString(bm.StopTime.Format(time.ANSIC))
+	builder.WriteByte(')')
+	return builder.String()
+}
+
+// BatchMsgs is a parsable slice of BatchMsg.
+type BatchMsgs []*BatchMsg

+ 162 - 0
ent/batchmsg/batchmsg.go

@@ -0,0 +1,162 @@
+// Code generated by ent, DO NOT EDIT.
+
+package batchmsg
+
+import (
+	"time"
+
+	"entgo.io/ent"
+	"entgo.io/ent/dialect/sql"
+)
+
+const (
+	// Label holds the string label denoting the batchmsg type in the database.
+	Label = "batch_msg"
+	// 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"
+	// FieldDeletedAt holds the string denoting the deleted_at field in the database.
+	FieldDeletedAt = "deleted_at"
+	// FieldStatus holds the string denoting the status field in the database.
+	FieldStatus = "status"
+	// FieldBatchNo holds the string denoting the batch_no field in the database.
+	FieldBatchNo = "batch_no"
+	// FieldFromwxid holds the string denoting the fromwxid field in the database.
+	FieldFromwxid = "fromwxid"
+	// FieldMsg holds the string denoting the msg field in the database.
+	FieldMsg = "msg"
+	// FieldTag holds the string denoting the tag field in the database.
+	FieldTag = "tag"
+	// FieldTotal holds the string denoting the total field in the database.
+	FieldTotal = "total"
+	// FieldSuccess holds the string denoting the success field in the database.
+	FieldSuccess = "success"
+	// FieldFail holds the string denoting the fail field in the database.
+	FieldFail = "fail"
+	// FieldStartTime holds the string denoting the start_time field in the database.
+	FieldStartTime = "start_time"
+	// FieldStopTime holds the string denoting the stop_time field in the database.
+	FieldStopTime = "stop_time"
+	// Table holds the table name of the batchmsg in the database.
+	Table = "batch_msgs"
+)
+
+// Columns holds all SQL columns for batchmsg fields.
+var Columns = []string{
+	FieldID,
+	FieldCreatedAt,
+	FieldUpdatedAt,
+	FieldDeletedAt,
+	FieldStatus,
+	FieldBatchNo,
+	FieldFromwxid,
+	FieldMsg,
+	FieldTag,
+	FieldTotal,
+	FieldSuccess,
+	FieldFail,
+	FieldStartTime,
+	FieldStopTime,
+}
+
+// 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
+}
+
+// Note that the variables below are initialized by the runtime
+// package on the initialization of the application. Therefore,
+// it should be imported in the main as follows:
+//
+//	import _ "wechat-api/ent/runtime"
+var (
+	Hooks        [1]ent.Hook
+	Interceptors [1]ent.Interceptor
+	// 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
+)
+
+// OrderOption defines the ordering options for the BatchMsg 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()
+}
+
+// ByDeletedAt orders the results by the deleted_at field.
+func ByDeletedAt(opts ...sql.OrderTermOption) OrderOption {
+	return sql.OrderByField(FieldDeletedAt, opts...).ToFunc()
+}
+
+// ByStatus orders the results by the status field.
+func ByStatus(opts ...sql.OrderTermOption) OrderOption {
+	return sql.OrderByField(FieldStatus, opts...).ToFunc()
+}
+
+// ByBatchNo orders the results by the batch_no field.
+func ByBatchNo(opts ...sql.OrderTermOption) OrderOption {
+	return sql.OrderByField(FieldBatchNo, opts...).ToFunc()
+}
+
+// ByFromwxid orders the results by the fromwxid field.
+func ByFromwxid(opts ...sql.OrderTermOption) OrderOption {
+	return sql.OrderByField(FieldFromwxid, opts...).ToFunc()
+}
+
+// ByMsg orders the results by the msg field.
+func ByMsg(opts ...sql.OrderTermOption) OrderOption {
+	return sql.OrderByField(FieldMsg, opts...).ToFunc()
+}
+
+// ByTag orders the results by the tag field.
+func ByTag(opts ...sql.OrderTermOption) OrderOption {
+	return sql.OrderByField(FieldTag, opts...).ToFunc()
+}
+
+// ByTotal orders the results by the total field.
+func ByTotal(opts ...sql.OrderTermOption) OrderOption {
+	return sql.OrderByField(FieldTotal, opts...).ToFunc()
+}
+
+// BySuccess orders the results by the success field.
+func BySuccess(opts ...sql.OrderTermOption) OrderOption {
+	return sql.OrderByField(FieldSuccess, opts...).ToFunc()
+}
+
+// ByFail orders the results by the fail field.
+func ByFail(opts ...sql.OrderTermOption) OrderOption {
+	return sql.OrderByField(FieldFail, opts...).ToFunc()
+}
+
+// ByStartTime orders the results by the start_time field.
+func ByStartTime(opts ...sql.OrderTermOption) OrderOption {
+	return sql.OrderByField(FieldStartTime, opts...).ToFunc()
+}
+
+// ByStopTime orders the results by the stop_time field.
+func ByStopTime(opts ...sql.OrderTermOption) OrderOption {
+	return sql.OrderByField(FieldStopTime, opts...).ToFunc()
+}

+ 865 - 0
ent/batchmsg/where.go

@@ -0,0 +1,865 @@
+// Code generated by ent, DO NOT EDIT.
+
+package batchmsg
+
+import (
+	"time"
+	"wechat-api/ent/predicate"
+
+	"entgo.io/ent/dialect/sql"
+)
+
+// ID filters vertices based on their ID field.
+func ID(id uint64) predicate.BatchMsg {
+	return predicate.BatchMsg(sql.FieldEQ(FieldID, id))
+}
+
+// IDEQ applies the EQ predicate on the ID field.
+func IDEQ(id uint64) predicate.BatchMsg {
+	return predicate.BatchMsg(sql.FieldEQ(FieldID, id))
+}
+
+// IDNEQ applies the NEQ predicate on the ID field.
+func IDNEQ(id uint64) predicate.BatchMsg {
+	return predicate.BatchMsg(sql.FieldNEQ(FieldID, id))
+}
+
+// IDIn applies the In predicate on the ID field.
+func IDIn(ids ...uint64) predicate.BatchMsg {
+	return predicate.BatchMsg(sql.FieldIn(FieldID, ids...))
+}
+
+// IDNotIn applies the NotIn predicate on the ID field.
+func IDNotIn(ids ...uint64) predicate.BatchMsg {
+	return predicate.BatchMsg(sql.FieldNotIn(FieldID, ids...))
+}
+
+// IDGT applies the GT predicate on the ID field.
+func IDGT(id uint64) predicate.BatchMsg {
+	return predicate.BatchMsg(sql.FieldGT(FieldID, id))
+}
+
+// IDGTE applies the GTE predicate on the ID field.
+func IDGTE(id uint64) predicate.BatchMsg {
+	return predicate.BatchMsg(sql.FieldGTE(FieldID, id))
+}
+
+// IDLT applies the LT predicate on the ID field.
+func IDLT(id uint64) predicate.BatchMsg {
+	return predicate.BatchMsg(sql.FieldLT(FieldID, id))
+}
+
+// IDLTE applies the LTE predicate on the ID field.
+func IDLTE(id uint64) predicate.BatchMsg {
+	return predicate.BatchMsg(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.BatchMsg {
+	return predicate.BatchMsg(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.BatchMsg {
+	return predicate.BatchMsg(sql.FieldEQ(FieldUpdatedAt, v))
+}
+
+// DeletedAt applies equality check predicate on the "deleted_at" field. It's identical to DeletedAtEQ.
+func DeletedAt(v time.Time) predicate.BatchMsg {
+	return predicate.BatchMsg(sql.FieldEQ(FieldDeletedAt, v))
+}
+
+// Status applies equality check predicate on the "status" field. It's identical to StatusEQ.
+func Status(v uint8) predicate.BatchMsg {
+	return predicate.BatchMsg(sql.FieldEQ(FieldStatus, v))
+}
+
+// BatchNo applies equality check predicate on the "batch_no" field. It's identical to BatchNoEQ.
+func BatchNo(v string) predicate.BatchMsg {
+	return predicate.BatchMsg(sql.FieldEQ(FieldBatchNo, v))
+}
+
+// Fromwxid applies equality check predicate on the "fromwxid" field. It's identical to FromwxidEQ.
+func Fromwxid(v string) predicate.BatchMsg {
+	return predicate.BatchMsg(sql.FieldEQ(FieldFromwxid, v))
+}
+
+// Msg applies equality check predicate on the "msg" field. It's identical to MsgEQ.
+func Msg(v string) predicate.BatchMsg {
+	return predicate.BatchMsg(sql.FieldEQ(FieldMsg, v))
+}
+
+// Tag applies equality check predicate on the "tag" field. It's identical to TagEQ.
+func Tag(v string) predicate.BatchMsg {
+	return predicate.BatchMsg(sql.FieldEQ(FieldTag, v))
+}
+
+// Total applies equality check predicate on the "total" field. It's identical to TotalEQ.
+func Total(v int32) predicate.BatchMsg {
+	return predicate.BatchMsg(sql.FieldEQ(FieldTotal, v))
+}
+
+// Success applies equality check predicate on the "success" field. It's identical to SuccessEQ.
+func Success(v int32) predicate.BatchMsg {
+	return predicate.BatchMsg(sql.FieldEQ(FieldSuccess, v))
+}
+
+// Fail applies equality check predicate on the "fail" field. It's identical to FailEQ.
+func Fail(v int32) predicate.BatchMsg {
+	return predicate.BatchMsg(sql.FieldEQ(FieldFail, v))
+}
+
+// StartTime applies equality check predicate on the "start_time" field. It's identical to StartTimeEQ.
+func StartTime(v time.Time) predicate.BatchMsg {
+	return predicate.BatchMsg(sql.FieldEQ(FieldStartTime, v))
+}
+
+// StopTime applies equality check predicate on the "stop_time" field. It's identical to StopTimeEQ.
+func StopTime(v time.Time) predicate.BatchMsg {
+	return predicate.BatchMsg(sql.FieldEQ(FieldStopTime, v))
+}
+
+// CreatedAtEQ applies the EQ predicate on the "created_at" field.
+func CreatedAtEQ(v time.Time) predicate.BatchMsg {
+	return predicate.BatchMsg(sql.FieldEQ(FieldCreatedAt, v))
+}
+
+// CreatedAtNEQ applies the NEQ predicate on the "created_at" field.
+func CreatedAtNEQ(v time.Time) predicate.BatchMsg {
+	return predicate.BatchMsg(sql.FieldNEQ(FieldCreatedAt, v))
+}
+
+// CreatedAtIn applies the In predicate on the "created_at" field.
+func CreatedAtIn(vs ...time.Time) predicate.BatchMsg {
+	return predicate.BatchMsg(sql.FieldIn(FieldCreatedAt, vs...))
+}
+
+// CreatedAtNotIn applies the NotIn predicate on the "created_at" field.
+func CreatedAtNotIn(vs ...time.Time) predicate.BatchMsg {
+	return predicate.BatchMsg(sql.FieldNotIn(FieldCreatedAt, vs...))
+}
+
+// CreatedAtGT applies the GT predicate on the "created_at" field.
+func CreatedAtGT(v time.Time) predicate.BatchMsg {
+	return predicate.BatchMsg(sql.FieldGT(FieldCreatedAt, v))
+}
+
+// CreatedAtGTE applies the GTE predicate on the "created_at" field.
+func CreatedAtGTE(v time.Time) predicate.BatchMsg {
+	return predicate.BatchMsg(sql.FieldGTE(FieldCreatedAt, v))
+}
+
+// CreatedAtLT applies the LT predicate on the "created_at" field.
+func CreatedAtLT(v time.Time) predicate.BatchMsg {
+	return predicate.BatchMsg(sql.FieldLT(FieldCreatedAt, v))
+}
+
+// CreatedAtLTE applies the LTE predicate on the "created_at" field.
+func CreatedAtLTE(v time.Time) predicate.BatchMsg {
+	return predicate.BatchMsg(sql.FieldLTE(FieldCreatedAt, v))
+}
+
+// UpdatedAtEQ applies the EQ predicate on the "updated_at" field.
+func UpdatedAtEQ(v time.Time) predicate.BatchMsg {
+	return predicate.BatchMsg(sql.FieldEQ(FieldUpdatedAt, v))
+}
+
+// UpdatedAtNEQ applies the NEQ predicate on the "updated_at" field.
+func UpdatedAtNEQ(v time.Time) predicate.BatchMsg {
+	return predicate.BatchMsg(sql.FieldNEQ(FieldUpdatedAt, v))
+}
+
+// UpdatedAtIn applies the In predicate on the "updated_at" field.
+func UpdatedAtIn(vs ...time.Time) predicate.BatchMsg {
+	return predicate.BatchMsg(sql.FieldIn(FieldUpdatedAt, vs...))
+}
+
+// UpdatedAtNotIn applies the NotIn predicate on the "updated_at" field.
+func UpdatedAtNotIn(vs ...time.Time) predicate.BatchMsg {
+	return predicate.BatchMsg(sql.FieldNotIn(FieldUpdatedAt, vs...))
+}
+
+// UpdatedAtGT applies the GT predicate on the "updated_at" field.
+func UpdatedAtGT(v time.Time) predicate.BatchMsg {
+	return predicate.BatchMsg(sql.FieldGT(FieldUpdatedAt, v))
+}
+
+// UpdatedAtGTE applies the GTE predicate on the "updated_at" field.
+func UpdatedAtGTE(v time.Time) predicate.BatchMsg {
+	return predicate.BatchMsg(sql.FieldGTE(FieldUpdatedAt, v))
+}
+
+// UpdatedAtLT applies the LT predicate on the "updated_at" field.
+func UpdatedAtLT(v time.Time) predicate.BatchMsg {
+	return predicate.BatchMsg(sql.FieldLT(FieldUpdatedAt, v))
+}
+
+// UpdatedAtLTE applies the LTE predicate on the "updated_at" field.
+func UpdatedAtLTE(v time.Time) predicate.BatchMsg {
+	return predicate.BatchMsg(sql.FieldLTE(FieldUpdatedAt, v))
+}
+
+// DeletedAtEQ applies the EQ predicate on the "deleted_at" field.
+func DeletedAtEQ(v time.Time) predicate.BatchMsg {
+	return predicate.BatchMsg(sql.FieldEQ(FieldDeletedAt, v))
+}
+
+// DeletedAtNEQ applies the NEQ predicate on the "deleted_at" field.
+func DeletedAtNEQ(v time.Time) predicate.BatchMsg {
+	return predicate.BatchMsg(sql.FieldNEQ(FieldDeletedAt, v))
+}
+
+// DeletedAtIn applies the In predicate on the "deleted_at" field.
+func DeletedAtIn(vs ...time.Time) predicate.BatchMsg {
+	return predicate.BatchMsg(sql.FieldIn(FieldDeletedAt, vs...))
+}
+
+// DeletedAtNotIn applies the NotIn predicate on the "deleted_at" field.
+func DeletedAtNotIn(vs ...time.Time) predicate.BatchMsg {
+	return predicate.BatchMsg(sql.FieldNotIn(FieldDeletedAt, vs...))
+}
+
+// DeletedAtGT applies the GT predicate on the "deleted_at" field.
+func DeletedAtGT(v time.Time) predicate.BatchMsg {
+	return predicate.BatchMsg(sql.FieldGT(FieldDeletedAt, v))
+}
+
+// DeletedAtGTE applies the GTE predicate on the "deleted_at" field.
+func DeletedAtGTE(v time.Time) predicate.BatchMsg {
+	return predicate.BatchMsg(sql.FieldGTE(FieldDeletedAt, v))
+}
+
+// DeletedAtLT applies the LT predicate on the "deleted_at" field.
+func DeletedAtLT(v time.Time) predicate.BatchMsg {
+	return predicate.BatchMsg(sql.FieldLT(FieldDeletedAt, v))
+}
+
+// DeletedAtLTE applies the LTE predicate on the "deleted_at" field.
+func DeletedAtLTE(v time.Time) predicate.BatchMsg {
+	return predicate.BatchMsg(sql.FieldLTE(FieldDeletedAt, v))
+}
+
+// DeletedAtIsNil applies the IsNil predicate on the "deleted_at" field.
+func DeletedAtIsNil() predicate.BatchMsg {
+	return predicate.BatchMsg(sql.FieldIsNull(FieldDeletedAt))
+}
+
+// DeletedAtNotNil applies the NotNil predicate on the "deleted_at" field.
+func DeletedAtNotNil() predicate.BatchMsg {
+	return predicate.BatchMsg(sql.FieldNotNull(FieldDeletedAt))
+}
+
+// StatusEQ applies the EQ predicate on the "status" field.
+func StatusEQ(v uint8) predicate.BatchMsg {
+	return predicate.BatchMsg(sql.FieldEQ(FieldStatus, v))
+}
+
+// StatusNEQ applies the NEQ predicate on the "status" field.
+func StatusNEQ(v uint8) predicate.BatchMsg {
+	return predicate.BatchMsg(sql.FieldNEQ(FieldStatus, v))
+}
+
+// StatusIn applies the In predicate on the "status" field.
+func StatusIn(vs ...uint8) predicate.BatchMsg {
+	return predicate.BatchMsg(sql.FieldIn(FieldStatus, vs...))
+}
+
+// StatusNotIn applies the NotIn predicate on the "status" field.
+func StatusNotIn(vs ...uint8) predicate.BatchMsg {
+	return predicate.BatchMsg(sql.FieldNotIn(FieldStatus, vs...))
+}
+
+// StatusGT applies the GT predicate on the "status" field.
+func StatusGT(v uint8) predicate.BatchMsg {
+	return predicate.BatchMsg(sql.FieldGT(FieldStatus, v))
+}
+
+// StatusGTE applies the GTE predicate on the "status" field.
+func StatusGTE(v uint8) predicate.BatchMsg {
+	return predicate.BatchMsg(sql.FieldGTE(FieldStatus, v))
+}
+
+// StatusLT applies the LT predicate on the "status" field.
+func StatusLT(v uint8) predicate.BatchMsg {
+	return predicate.BatchMsg(sql.FieldLT(FieldStatus, v))
+}
+
+// StatusLTE applies the LTE predicate on the "status" field.
+func StatusLTE(v uint8) predicate.BatchMsg {
+	return predicate.BatchMsg(sql.FieldLTE(FieldStatus, v))
+}
+
+// StatusIsNil applies the IsNil predicate on the "status" field.
+func StatusIsNil() predicate.BatchMsg {
+	return predicate.BatchMsg(sql.FieldIsNull(FieldStatus))
+}
+
+// StatusNotNil applies the NotNil predicate on the "status" field.
+func StatusNotNil() predicate.BatchMsg {
+	return predicate.BatchMsg(sql.FieldNotNull(FieldStatus))
+}
+
+// BatchNoEQ applies the EQ predicate on the "batch_no" field.
+func BatchNoEQ(v string) predicate.BatchMsg {
+	return predicate.BatchMsg(sql.FieldEQ(FieldBatchNo, v))
+}
+
+// BatchNoNEQ applies the NEQ predicate on the "batch_no" field.
+func BatchNoNEQ(v string) predicate.BatchMsg {
+	return predicate.BatchMsg(sql.FieldNEQ(FieldBatchNo, v))
+}
+
+// BatchNoIn applies the In predicate on the "batch_no" field.
+func BatchNoIn(vs ...string) predicate.BatchMsg {
+	return predicate.BatchMsg(sql.FieldIn(FieldBatchNo, vs...))
+}
+
+// BatchNoNotIn applies the NotIn predicate on the "batch_no" field.
+func BatchNoNotIn(vs ...string) predicate.BatchMsg {
+	return predicate.BatchMsg(sql.FieldNotIn(FieldBatchNo, vs...))
+}
+
+// BatchNoGT applies the GT predicate on the "batch_no" field.
+func BatchNoGT(v string) predicate.BatchMsg {
+	return predicate.BatchMsg(sql.FieldGT(FieldBatchNo, v))
+}
+
+// BatchNoGTE applies the GTE predicate on the "batch_no" field.
+func BatchNoGTE(v string) predicate.BatchMsg {
+	return predicate.BatchMsg(sql.FieldGTE(FieldBatchNo, v))
+}
+
+// BatchNoLT applies the LT predicate on the "batch_no" field.
+func BatchNoLT(v string) predicate.BatchMsg {
+	return predicate.BatchMsg(sql.FieldLT(FieldBatchNo, v))
+}
+
+// BatchNoLTE applies the LTE predicate on the "batch_no" field.
+func BatchNoLTE(v string) predicate.BatchMsg {
+	return predicate.BatchMsg(sql.FieldLTE(FieldBatchNo, v))
+}
+
+// BatchNoContains applies the Contains predicate on the "batch_no" field.
+func BatchNoContains(v string) predicate.BatchMsg {
+	return predicate.BatchMsg(sql.FieldContains(FieldBatchNo, v))
+}
+
+// BatchNoHasPrefix applies the HasPrefix predicate on the "batch_no" field.
+func BatchNoHasPrefix(v string) predicate.BatchMsg {
+	return predicate.BatchMsg(sql.FieldHasPrefix(FieldBatchNo, v))
+}
+
+// BatchNoHasSuffix applies the HasSuffix predicate on the "batch_no" field.
+func BatchNoHasSuffix(v string) predicate.BatchMsg {
+	return predicate.BatchMsg(sql.FieldHasSuffix(FieldBatchNo, v))
+}
+
+// BatchNoIsNil applies the IsNil predicate on the "batch_no" field.
+func BatchNoIsNil() predicate.BatchMsg {
+	return predicate.BatchMsg(sql.FieldIsNull(FieldBatchNo))
+}
+
+// BatchNoNotNil applies the NotNil predicate on the "batch_no" field.
+func BatchNoNotNil() predicate.BatchMsg {
+	return predicate.BatchMsg(sql.FieldNotNull(FieldBatchNo))
+}
+
+// BatchNoEqualFold applies the EqualFold predicate on the "batch_no" field.
+func BatchNoEqualFold(v string) predicate.BatchMsg {
+	return predicate.BatchMsg(sql.FieldEqualFold(FieldBatchNo, v))
+}
+
+// BatchNoContainsFold applies the ContainsFold predicate on the "batch_no" field.
+func BatchNoContainsFold(v string) predicate.BatchMsg {
+	return predicate.BatchMsg(sql.FieldContainsFold(FieldBatchNo, v))
+}
+
+// FromwxidEQ applies the EQ predicate on the "fromwxid" field.
+func FromwxidEQ(v string) predicate.BatchMsg {
+	return predicate.BatchMsg(sql.FieldEQ(FieldFromwxid, v))
+}
+
+// FromwxidNEQ applies the NEQ predicate on the "fromwxid" field.
+func FromwxidNEQ(v string) predicate.BatchMsg {
+	return predicate.BatchMsg(sql.FieldNEQ(FieldFromwxid, v))
+}
+
+// FromwxidIn applies the In predicate on the "fromwxid" field.
+func FromwxidIn(vs ...string) predicate.BatchMsg {
+	return predicate.BatchMsg(sql.FieldIn(FieldFromwxid, vs...))
+}
+
+// FromwxidNotIn applies the NotIn predicate on the "fromwxid" field.
+func FromwxidNotIn(vs ...string) predicate.BatchMsg {
+	return predicate.BatchMsg(sql.FieldNotIn(FieldFromwxid, vs...))
+}
+
+// FromwxidGT applies the GT predicate on the "fromwxid" field.
+func FromwxidGT(v string) predicate.BatchMsg {
+	return predicate.BatchMsg(sql.FieldGT(FieldFromwxid, v))
+}
+
+// FromwxidGTE applies the GTE predicate on the "fromwxid" field.
+func FromwxidGTE(v string) predicate.BatchMsg {
+	return predicate.BatchMsg(sql.FieldGTE(FieldFromwxid, v))
+}
+
+// FromwxidLT applies the LT predicate on the "fromwxid" field.
+func FromwxidLT(v string) predicate.BatchMsg {
+	return predicate.BatchMsg(sql.FieldLT(FieldFromwxid, v))
+}
+
+// FromwxidLTE applies the LTE predicate on the "fromwxid" field.
+func FromwxidLTE(v string) predicate.BatchMsg {
+	return predicate.BatchMsg(sql.FieldLTE(FieldFromwxid, v))
+}
+
+// FromwxidContains applies the Contains predicate on the "fromwxid" field.
+func FromwxidContains(v string) predicate.BatchMsg {
+	return predicate.BatchMsg(sql.FieldContains(FieldFromwxid, v))
+}
+
+// FromwxidHasPrefix applies the HasPrefix predicate on the "fromwxid" field.
+func FromwxidHasPrefix(v string) predicate.BatchMsg {
+	return predicate.BatchMsg(sql.FieldHasPrefix(FieldFromwxid, v))
+}
+
+// FromwxidHasSuffix applies the HasSuffix predicate on the "fromwxid" field.
+func FromwxidHasSuffix(v string) predicate.BatchMsg {
+	return predicate.BatchMsg(sql.FieldHasSuffix(FieldFromwxid, v))
+}
+
+// FromwxidIsNil applies the IsNil predicate on the "fromwxid" field.
+func FromwxidIsNil() predicate.BatchMsg {
+	return predicate.BatchMsg(sql.FieldIsNull(FieldFromwxid))
+}
+
+// FromwxidNotNil applies the NotNil predicate on the "fromwxid" field.
+func FromwxidNotNil() predicate.BatchMsg {
+	return predicate.BatchMsg(sql.FieldNotNull(FieldFromwxid))
+}
+
+// FromwxidEqualFold applies the EqualFold predicate on the "fromwxid" field.
+func FromwxidEqualFold(v string) predicate.BatchMsg {
+	return predicate.BatchMsg(sql.FieldEqualFold(FieldFromwxid, v))
+}
+
+// FromwxidContainsFold applies the ContainsFold predicate on the "fromwxid" field.
+func FromwxidContainsFold(v string) predicate.BatchMsg {
+	return predicate.BatchMsg(sql.FieldContainsFold(FieldFromwxid, v))
+}
+
+// MsgEQ applies the EQ predicate on the "msg" field.
+func MsgEQ(v string) predicate.BatchMsg {
+	return predicate.BatchMsg(sql.FieldEQ(FieldMsg, v))
+}
+
+// MsgNEQ applies the NEQ predicate on the "msg" field.
+func MsgNEQ(v string) predicate.BatchMsg {
+	return predicate.BatchMsg(sql.FieldNEQ(FieldMsg, v))
+}
+
+// MsgIn applies the In predicate on the "msg" field.
+func MsgIn(vs ...string) predicate.BatchMsg {
+	return predicate.BatchMsg(sql.FieldIn(FieldMsg, vs...))
+}
+
+// MsgNotIn applies the NotIn predicate on the "msg" field.
+func MsgNotIn(vs ...string) predicate.BatchMsg {
+	return predicate.BatchMsg(sql.FieldNotIn(FieldMsg, vs...))
+}
+
+// MsgGT applies the GT predicate on the "msg" field.
+func MsgGT(v string) predicate.BatchMsg {
+	return predicate.BatchMsg(sql.FieldGT(FieldMsg, v))
+}
+
+// MsgGTE applies the GTE predicate on the "msg" field.
+func MsgGTE(v string) predicate.BatchMsg {
+	return predicate.BatchMsg(sql.FieldGTE(FieldMsg, v))
+}
+
+// MsgLT applies the LT predicate on the "msg" field.
+func MsgLT(v string) predicate.BatchMsg {
+	return predicate.BatchMsg(sql.FieldLT(FieldMsg, v))
+}
+
+// MsgLTE applies the LTE predicate on the "msg" field.
+func MsgLTE(v string) predicate.BatchMsg {
+	return predicate.BatchMsg(sql.FieldLTE(FieldMsg, v))
+}
+
+// MsgContains applies the Contains predicate on the "msg" field.
+func MsgContains(v string) predicate.BatchMsg {
+	return predicate.BatchMsg(sql.FieldContains(FieldMsg, v))
+}
+
+// MsgHasPrefix applies the HasPrefix predicate on the "msg" field.
+func MsgHasPrefix(v string) predicate.BatchMsg {
+	return predicate.BatchMsg(sql.FieldHasPrefix(FieldMsg, v))
+}
+
+// MsgHasSuffix applies the HasSuffix predicate on the "msg" field.
+func MsgHasSuffix(v string) predicate.BatchMsg {
+	return predicate.BatchMsg(sql.FieldHasSuffix(FieldMsg, v))
+}
+
+// MsgIsNil applies the IsNil predicate on the "msg" field.
+func MsgIsNil() predicate.BatchMsg {
+	return predicate.BatchMsg(sql.FieldIsNull(FieldMsg))
+}
+
+// MsgNotNil applies the NotNil predicate on the "msg" field.
+func MsgNotNil() predicate.BatchMsg {
+	return predicate.BatchMsg(sql.FieldNotNull(FieldMsg))
+}
+
+// MsgEqualFold applies the EqualFold predicate on the "msg" field.
+func MsgEqualFold(v string) predicate.BatchMsg {
+	return predicate.BatchMsg(sql.FieldEqualFold(FieldMsg, v))
+}
+
+// MsgContainsFold applies the ContainsFold predicate on the "msg" field.
+func MsgContainsFold(v string) predicate.BatchMsg {
+	return predicate.BatchMsg(sql.FieldContainsFold(FieldMsg, v))
+}
+
+// TagEQ applies the EQ predicate on the "tag" field.
+func TagEQ(v string) predicate.BatchMsg {
+	return predicate.BatchMsg(sql.FieldEQ(FieldTag, v))
+}
+
+// TagNEQ applies the NEQ predicate on the "tag" field.
+func TagNEQ(v string) predicate.BatchMsg {
+	return predicate.BatchMsg(sql.FieldNEQ(FieldTag, v))
+}
+
+// TagIn applies the In predicate on the "tag" field.
+func TagIn(vs ...string) predicate.BatchMsg {
+	return predicate.BatchMsg(sql.FieldIn(FieldTag, vs...))
+}
+
+// TagNotIn applies the NotIn predicate on the "tag" field.
+func TagNotIn(vs ...string) predicate.BatchMsg {
+	return predicate.BatchMsg(sql.FieldNotIn(FieldTag, vs...))
+}
+
+// TagGT applies the GT predicate on the "tag" field.
+func TagGT(v string) predicate.BatchMsg {
+	return predicate.BatchMsg(sql.FieldGT(FieldTag, v))
+}
+
+// TagGTE applies the GTE predicate on the "tag" field.
+func TagGTE(v string) predicate.BatchMsg {
+	return predicate.BatchMsg(sql.FieldGTE(FieldTag, v))
+}
+
+// TagLT applies the LT predicate on the "tag" field.
+func TagLT(v string) predicate.BatchMsg {
+	return predicate.BatchMsg(sql.FieldLT(FieldTag, v))
+}
+
+// TagLTE applies the LTE predicate on the "tag" field.
+func TagLTE(v string) predicate.BatchMsg {
+	return predicate.BatchMsg(sql.FieldLTE(FieldTag, v))
+}
+
+// TagContains applies the Contains predicate on the "tag" field.
+func TagContains(v string) predicate.BatchMsg {
+	return predicate.BatchMsg(sql.FieldContains(FieldTag, v))
+}
+
+// TagHasPrefix applies the HasPrefix predicate on the "tag" field.
+func TagHasPrefix(v string) predicate.BatchMsg {
+	return predicate.BatchMsg(sql.FieldHasPrefix(FieldTag, v))
+}
+
+// TagHasSuffix applies the HasSuffix predicate on the "tag" field.
+func TagHasSuffix(v string) predicate.BatchMsg {
+	return predicate.BatchMsg(sql.FieldHasSuffix(FieldTag, v))
+}
+
+// TagIsNil applies the IsNil predicate on the "tag" field.
+func TagIsNil() predicate.BatchMsg {
+	return predicate.BatchMsg(sql.FieldIsNull(FieldTag))
+}
+
+// TagNotNil applies the NotNil predicate on the "tag" field.
+func TagNotNil() predicate.BatchMsg {
+	return predicate.BatchMsg(sql.FieldNotNull(FieldTag))
+}
+
+// TagEqualFold applies the EqualFold predicate on the "tag" field.
+func TagEqualFold(v string) predicate.BatchMsg {
+	return predicate.BatchMsg(sql.FieldEqualFold(FieldTag, v))
+}
+
+// TagContainsFold applies the ContainsFold predicate on the "tag" field.
+func TagContainsFold(v string) predicate.BatchMsg {
+	return predicate.BatchMsg(sql.FieldContainsFold(FieldTag, v))
+}
+
+// TotalEQ applies the EQ predicate on the "total" field.
+func TotalEQ(v int32) predicate.BatchMsg {
+	return predicate.BatchMsg(sql.FieldEQ(FieldTotal, v))
+}
+
+// TotalNEQ applies the NEQ predicate on the "total" field.
+func TotalNEQ(v int32) predicate.BatchMsg {
+	return predicate.BatchMsg(sql.FieldNEQ(FieldTotal, v))
+}
+
+// TotalIn applies the In predicate on the "total" field.
+func TotalIn(vs ...int32) predicate.BatchMsg {
+	return predicate.BatchMsg(sql.FieldIn(FieldTotal, vs...))
+}
+
+// TotalNotIn applies the NotIn predicate on the "total" field.
+func TotalNotIn(vs ...int32) predicate.BatchMsg {
+	return predicate.BatchMsg(sql.FieldNotIn(FieldTotal, vs...))
+}
+
+// TotalGT applies the GT predicate on the "total" field.
+func TotalGT(v int32) predicate.BatchMsg {
+	return predicate.BatchMsg(sql.FieldGT(FieldTotal, v))
+}
+
+// TotalGTE applies the GTE predicate on the "total" field.
+func TotalGTE(v int32) predicate.BatchMsg {
+	return predicate.BatchMsg(sql.FieldGTE(FieldTotal, v))
+}
+
+// TotalLT applies the LT predicate on the "total" field.
+func TotalLT(v int32) predicate.BatchMsg {
+	return predicate.BatchMsg(sql.FieldLT(FieldTotal, v))
+}
+
+// TotalLTE applies the LTE predicate on the "total" field.
+func TotalLTE(v int32) predicate.BatchMsg {
+	return predicate.BatchMsg(sql.FieldLTE(FieldTotal, v))
+}
+
+// TotalIsNil applies the IsNil predicate on the "total" field.
+func TotalIsNil() predicate.BatchMsg {
+	return predicate.BatchMsg(sql.FieldIsNull(FieldTotal))
+}
+
+// TotalNotNil applies the NotNil predicate on the "total" field.
+func TotalNotNil() predicate.BatchMsg {
+	return predicate.BatchMsg(sql.FieldNotNull(FieldTotal))
+}
+
+// SuccessEQ applies the EQ predicate on the "success" field.
+func SuccessEQ(v int32) predicate.BatchMsg {
+	return predicate.BatchMsg(sql.FieldEQ(FieldSuccess, v))
+}
+
+// SuccessNEQ applies the NEQ predicate on the "success" field.
+func SuccessNEQ(v int32) predicate.BatchMsg {
+	return predicate.BatchMsg(sql.FieldNEQ(FieldSuccess, v))
+}
+
+// SuccessIn applies the In predicate on the "success" field.
+func SuccessIn(vs ...int32) predicate.BatchMsg {
+	return predicate.BatchMsg(sql.FieldIn(FieldSuccess, vs...))
+}
+
+// SuccessNotIn applies the NotIn predicate on the "success" field.
+func SuccessNotIn(vs ...int32) predicate.BatchMsg {
+	return predicate.BatchMsg(sql.FieldNotIn(FieldSuccess, vs...))
+}
+
+// SuccessGT applies the GT predicate on the "success" field.
+func SuccessGT(v int32) predicate.BatchMsg {
+	return predicate.BatchMsg(sql.FieldGT(FieldSuccess, v))
+}
+
+// SuccessGTE applies the GTE predicate on the "success" field.
+func SuccessGTE(v int32) predicate.BatchMsg {
+	return predicate.BatchMsg(sql.FieldGTE(FieldSuccess, v))
+}
+
+// SuccessLT applies the LT predicate on the "success" field.
+func SuccessLT(v int32) predicate.BatchMsg {
+	return predicate.BatchMsg(sql.FieldLT(FieldSuccess, v))
+}
+
+// SuccessLTE applies the LTE predicate on the "success" field.
+func SuccessLTE(v int32) predicate.BatchMsg {
+	return predicate.BatchMsg(sql.FieldLTE(FieldSuccess, v))
+}
+
+// SuccessIsNil applies the IsNil predicate on the "success" field.
+func SuccessIsNil() predicate.BatchMsg {
+	return predicate.BatchMsg(sql.FieldIsNull(FieldSuccess))
+}
+
+// SuccessNotNil applies the NotNil predicate on the "success" field.
+func SuccessNotNil() predicate.BatchMsg {
+	return predicate.BatchMsg(sql.FieldNotNull(FieldSuccess))
+}
+
+// FailEQ applies the EQ predicate on the "fail" field.
+func FailEQ(v int32) predicate.BatchMsg {
+	return predicate.BatchMsg(sql.FieldEQ(FieldFail, v))
+}
+
+// FailNEQ applies the NEQ predicate on the "fail" field.
+func FailNEQ(v int32) predicate.BatchMsg {
+	return predicate.BatchMsg(sql.FieldNEQ(FieldFail, v))
+}
+
+// FailIn applies the In predicate on the "fail" field.
+func FailIn(vs ...int32) predicate.BatchMsg {
+	return predicate.BatchMsg(sql.FieldIn(FieldFail, vs...))
+}
+
+// FailNotIn applies the NotIn predicate on the "fail" field.
+func FailNotIn(vs ...int32) predicate.BatchMsg {
+	return predicate.BatchMsg(sql.FieldNotIn(FieldFail, vs...))
+}
+
+// FailGT applies the GT predicate on the "fail" field.
+func FailGT(v int32) predicate.BatchMsg {
+	return predicate.BatchMsg(sql.FieldGT(FieldFail, v))
+}
+
+// FailGTE applies the GTE predicate on the "fail" field.
+func FailGTE(v int32) predicate.BatchMsg {
+	return predicate.BatchMsg(sql.FieldGTE(FieldFail, v))
+}
+
+// FailLT applies the LT predicate on the "fail" field.
+func FailLT(v int32) predicate.BatchMsg {
+	return predicate.BatchMsg(sql.FieldLT(FieldFail, v))
+}
+
+// FailLTE applies the LTE predicate on the "fail" field.
+func FailLTE(v int32) predicate.BatchMsg {
+	return predicate.BatchMsg(sql.FieldLTE(FieldFail, v))
+}
+
+// FailIsNil applies the IsNil predicate on the "fail" field.
+func FailIsNil() predicate.BatchMsg {
+	return predicate.BatchMsg(sql.FieldIsNull(FieldFail))
+}
+
+// FailNotNil applies the NotNil predicate on the "fail" field.
+func FailNotNil() predicate.BatchMsg {
+	return predicate.BatchMsg(sql.FieldNotNull(FieldFail))
+}
+
+// StartTimeEQ applies the EQ predicate on the "start_time" field.
+func StartTimeEQ(v time.Time) predicate.BatchMsg {
+	return predicate.BatchMsg(sql.FieldEQ(FieldStartTime, v))
+}
+
+// StartTimeNEQ applies the NEQ predicate on the "start_time" field.
+func StartTimeNEQ(v time.Time) predicate.BatchMsg {
+	return predicate.BatchMsg(sql.FieldNEQ(FieldStartTime, v))
+}
+
+// StartTimeIn applies the In predicate on the "start_time" field.
+func StartTimeIn(vs ...time.Time) predicate.BatchMsg {
+	return predicate.BatchMsg(sql.FieldIn(FieldStartTime, vs...))
+}
+
+// StartTimeNotIn applies the NotIn predicate on the "start_time" field.
+func StartTimeNotIn(vs ...time.Time) predicate.BatchMsg {
+	return predicate.BatchMsg(sql.FieldNotIn(FieldStartTime, vs...))
+}
+
+// StartTimeGT applies the GT predicate on the "start_time" field.
+func StartTimeGT(v time.Time) predicate.BatchMsg {
+	return predicate.BatchMsg(sql.FieldGT(FieldStartTime, v))
+}
+
+// StartTimeGTE applies the GTE predicate on the "start_time" field.
+func StartTimeGTE(v time.Time) predicate.BatchMsg {
+	return predicate.BatchMsg(sql.FieldGTE(FieldStartTime, v))
+}
+
+// StartTimeLT applies the LT predicate on the "start_time" field.
+func StartTimeLT(v time.Time) predicate.BatchMsg {
+	return predicate.BatchMsg(sql.FieldLT(FieldStartTime, v))
+}
+
+// StartTimeLTE applies the LTE predicate on the "start_time" field.
+func StartTimeLTE(v time.Time) predicate.BatchMsg {
+	return predicate.BatchMsg(sql.FieldLTE(FieldStartTime, v))
+}
+
+// StartTimeIsNil applies the IsNil predicate on the "start_time" field.
+func StartTimeIsNil() predicate.BatchMsg {
+	return predicate.BatchMsg(sql.FieldIsNull(FieldStartTime))
+}
+
+// StartTimeNotNil applies the NotNil predicate on the "start_time" field.
+func StartTimeNotNil() predicate.BatchMsg {
+	return predicate.BatchMsg(sql.FieldNotNull(FieldStartTime))
+}
+
+// StopTimeEQ applies the EQ predicate on the "stop_time" field.
+func StopTimeEQ(v time.Time) predicate.BatchMsg {
+	return predicate.BatchMsg(sql.FieldEQ(FieldStopTime, v))
+}
+
+// StopTimeNEQ applies the NEQ predicate on the "stop_time" field.
+func StopTimeNEQ(v time.Time) predicate.BatchMsg {
+	return predicate.BatchMsg(sql.FieldNEQ(FieldStopTime, v))
+}
+
+// StopTimeIn applies the In predicate on the "stop_time" field.
+func StopTimeIn(vs ...time.Time) predicate.BatchMsg {
+	return predicate.BatchMsg(sql.FieldIn(FieldStopTime, vs...))
+}
+
+// StopTimeNotIn applies the NotIn predicate on the "stop_time" field.
+func StopTimeNotIn(vs ...time.Time) predicate.BatchMsg {
+	return predicate.BatchMsg(sql.FieldNotIn(FieldStopTime, vs...))
+}
+
+// StopTimeGT applies the GT predicate on the "stop_time" field.
+func StopTimeGT(v time.Time) predicate.BatchMsg {
+	return predicate.BatchMsg(sql.FieldGT(FieldStopTime, v))
+}
+
+// StopTimeGTE applies the GTE predicate on the "stop_time" field.
+func StopTimeGTE(v time.Time) predicate.BatchMsg {
+	return predicate.BatchMsg(sql.FieldGTE(FieldStopTime, v))
+}
+
+// StopTimeLT applies the LT predicate on the "stop_time" field.
+func StopTimeLT(v time.Time) predicate.BatchMsg {
+	return predicate.BatchMsg(sql.FieldLT(FieldStopTime, v))
+}
+
+// StopTimeLTE applies the LTE predicate on the "stop_time" field.
+func StopTimeLTE(v time.Time) predicate.BatchMsg {
+	return predicate.BatchMsg(sql.FieldLTE(FieldStopTime, v))
+}
+
+// StopTimeIsNil applies the IsNil predicate on the "stop_time" field.
+func StopTimeIsNil() predicate.BatchMsg {
+	return predicate.BatchMsg(sql.FieldIsNull(FieldStopTime))
+}
+
+// StopTimeNotNil applies the NotNil predicate on the "stop_time" field.
+func StopTimeNotNil() predicate.BatchMsg {
+	return predicate.BatchMsg(sql.FieldNotNull(FieldStopTime))
+}
+
+// And groups predicates with the AND operator between them.
+func And(predicates ...predicate.BatchMsg) predicate.BatchMsg {
+	return predicate.BatchMsg(sql.AndPredicates(predicates...))
+}
+
+// Or groups predicates with the OR operator between them.
+func Or(predicates ...predicate.BatchMsg) predicate.BatchMsg {
+	return predicate.BatchMsg(sql.OrPredicates(predicates...))
+}
+
+// Not applies the not operator on the given predicate.
+func Not(p predicate.BatchMsg) predicate.BatchMsg {
+	return predicate.BatchMsg(sql.NotPredicates(p))
+}

+ 1481 - 0
ent/batchmsg_create.go

@@ -0,0 +1,1481 @@
+// Code generated by ent, DO NOT EDIT.
+
+package ent
+
+import (
+	"context"
+	"errors"
+	"fmt"
+	"time"
+	"wechat-api/ent/batchmsg"
+
+	"entgo.io/ent/dialect/sql"
+	"entgo.io/ent/dialect/sql/sqlgraph"
+	"entgo.io/ent/schema/field"
+)
+
+// BatchMsgCreate is the builder for creating a BatchMsg entity.
+type BatchMsgCreate struct {
+	config
+	mutation *BatchMsgMutation
+	hooks    []Hook
+	conflict []sql.ConflictOption
+}
+
+// SetCreatedAt sets the "created_at" field.
+func (bmc *BatchMsgCreate) SetCreatedAt(t time.Time) *BatchMsgCreate {
+	bmc.mutation.SetCreatedAt(t)
+	return bmc
+}
+
+// SetNillableCreatedAt sets the "created_at" field if the given value is not nil.
+func (bmc *BatchMsgCreate) SetNillableCreatedAt(t *time.Time) *BatchMsgCreate {
+	if t != nil {
+		bmc.SetCreatedAt(*t)
+	}
+	return bmc
+}
+
+// SetUpdatedAt sets the "updated_at" field.
+func (bmc *BatchMsgCreate) SetUpdatedAt(t time.Time) *BatchMsgCreate {
+	bmc.mutation.SetUpdatedAt(t)
+	return bmc
+}
+
+// SetNillableUpdatedAt sets the "updated_at" field if the given value is not nil.
+func (bmc *BatchMsgCreate) SetNillableUpdatedAt(t *time.Time) *BatchMsgCreate {
+	if t != nil {
+		bmc.SetUpdatedAt(*t)
+	}
+	return bmc
+}
+
+// SetDeletedAt sets the "deleted_at" field.
+func (bmc *BatchMsgCreate) SetDeletedAt(t time.Time) *BatchMsgCreate {
+	bmc.mutation.SetDeletedAt(t)
+	return bmc
+}
+
+// SetNillableDeletedAt sets the "deleted_at" field if the given value is not nil.
+func (bmc *BatchMsgCreate) SetNillableDeletedAt(t *time.Time) *BatchMsgCreate {
+	if t != nil {
+		bmc.SetDeletedAt(*t)
+	}
+	return bmc
+}
+
+// SetStatus sets the "status" field.
+func (bmc *BatchMsgCreate) SetStatus(u uint8) *BatchMsgCreate {
+	bmc.mutation.SetStatus(u)
+	return bmc
+}
+
+// SetNillableStatus sets the "status" field if the given value is not nil.
+func (bmc *BatchMsgCreate) SetNillableStatus(u *uint8) *BatchMsgCreate {
+	if u != nil {
+		bmc.SetStatus(*u)
+	}
+	return bmc
+}
+
+// SetBatchNo sets the "batch_no" field.
+func (bmc *BatchMsgCreate) SetBatchNo(s string) *BatchMsgCreate {
+	bmc.mutation.SetBatchNo(s)
+	return bmc
+}
+
+// SetNillableBatchNo sets the "batch_no" field if the given value is not nil.
+func (bmc *BatchMsgCreate) SetNillableBatchNo(s *string) *BatchMsgCreate {
+	if s != nil {
+		bmc.SetBatchNo(*s)
+	}
+	return bmc
+}
+
+// SetFromwxid sets the "fromwxid" field.
+func (bmc *BatchMsgCreate) SetFromwxid(s string) *BatchMsgCreate {
+	bmc.mutation.SetFromwxid(s)
+	return bmc
+}
+
+// SetNillableFromwxid sets the "fromwxid" field if the given value is not nil.
+func (bmc *BatchMsgCreate) SetNillableFromwxid(s *string) *BatchMsgCreate {
+	if s != nil {
+		bmc.SetFromwxid(*s)
+	}
+	return bmc
+}
+
+// SetMsg sets the "msg" field.
+func (bmc *BatchMsgCreate) SetMsg(s string) *BatchMsgCreate {
+	bmc.mutation.SetMsg(s)
+	return bmc
+}
+
+// SetNillableMsg sets the "msg" field if the given value is not nil.
+func (bmc *BatchMsgCreate) SetNillableMsg(s *string) *BatchMsgCreate {
+	if s != nil {
+		bmc.SetMsg(*s)
+	}
+	return bmc
+}
+
+// SetTag sets the "tag" field.
+func (bmc *BatchMsgCreate) SetTag(s string) *BatchMsgCreate {
+	bmc.mutation.SetTag(s)
+	return bmc
+}
+
+// SetNillableTag sets the "tag" field if the given value is not nil.
+func (bmc *BatchMsgCreate) SetNillableTag(s *string) *BatchMsgCreate {
+	if s != nil {
+		bmc.SetTag(*s)
+	}
+	return bmc
+}
+
+// SetTotal sets the "total" field.
+func (bmc *BatchMsgCreate) SetTotal(i int32) *BatchMsgCreate {
+	bmc.mutation.SetTotal(i)
+	return bmc
+}
+
+// SetNillableTotal sets the "total" field if the given value is not nil.
+func (bmc *BatchMsgCreate) SetNillableTotal(i *int32) *BatchMsgCreate {
+	if i != nil {
+		bmc.SetTotal(*i)
+	}
+	return bmc
+}
+
+// SetSuccess sets the "success" field.
+func (bmc *BatchMsgCreate) SetSuccess(i int32) *BatchMsgCreate {
+	bmc.mutation.SetSuccess(i)
+	return bmc
+}
+
+// SetNillableSuccess sets the "success" field if the given value is not nil.
+func (bmc *BatchMsgCreate) SetNillableSuccess(i *int32) *BatchMsgCreate {
+	if i != nil {
+		bmc.SetSuccess(*i)
+	}
+	return bmc
+}
+
+// SetFail sets the "fail" field.
+func (bmc *BatchMsgCreate) SetFail(i int32) *BatchMsgCreate {
+	bmc.mutation.SetFail(i)
+	return bmc
+}
+
+// SetNillableFail sets the "fail" field if the given value is not nil.
+func (bmc *BatchMsgCreate) SetNillableFail(i *int32) *BatchMsgCreate {
+	if i != nil {
+		bmc.SetFail(*i)
+	}
+	return bmc
+}
+
+// SetStartTime sets the "start_time" field.
+func (bmc *BatchMsgCreate) SetStartTime(t time.Time) *BatchMsgCreate {
+	bmc.mutation.SetStartTime(t)
+	return bmc
+}
+
+// SetNillableStartTime sets the "start_time" field if the given value is not nil.
+func (bmc *BatchMsgCreate) SetNillableStartTime(t *time.Time) *BatchMsgCreate {
+	if t != nil {
+		bmc.SetStartTime(*t)
+	}
+	return bmc
+}
+
+// SetStopTime sets the "stop_time" field.
+func (bmc *BatchMsgCreate) SetStopTime(t time.Time) *BatchMsgCreate {
+	bmc.mutation.SetStopTime(t)
+	return bmc
+}
+
+// SetNillableStopTime sets the "stop_time" field if the given value is not nil.
+func (bmc *BatchMsgCreate) SetNillableStopTime(t *time.Time) *BatchMsgCreate {
+	if t != nil {
+		bmc.SetStopTime(*t)
+	}
+	return bmc
+}
+
+// SetID sets the "id" field.
+func (bmc *BatchMsgCreate) SetID(u uint64) *BatchMsgCreate {
+	bmc.mutation.SetID(u)
+	return bmc
+}
+
+// Mutation returns the BatchMsgMutation object of the builder.
+func (bmc *BatchMsgCreate) Mutation() *BatchMsgMutation {
+	return bmc.mutation
+}
+
+// Save creates the BatchMsg in the database.
+func (bmc *BatchMsgCreate) Save(ctx context.Context) (*BatchMsg, error) {
+	if err := bmc.defaults(); err != nil {
+		return nil, err
+	}
+	return withHooks(ctx, bmc.sqlSave, bmc.mutation, bmc.hooks)
+}
+
+// SaveX calls Save and panics if Save returns an error.
+func (bmc *BatchMsgCreate) SaveX(ctx context.Context) *BatchMsg {
+	v, err := bmc.Save(ctx)
+	if err != nil {
+		panic(err)
+	}
+	return v
+}
+
+// Exec executes the query.
+func (bmc *BatchMsgCreate) Exec(ctx context.Context) error {
+	_, err := bmc.Save(ctx)
+	return err
+}
+
+// ExecX is like Exec, but panics if an error occurs.
+func (bmc *BatchMsgCreate) ExecX(ctx context.Context) {
+	if err := bmc.Exec(ctx); err != nil {
+		panic(err)
+	}
+}
+
+// defaults sets the default values of the builder before save.
+func (bmc *BatchMsgCreate) defaults() error {
+	if _, ok := bmc.mutation.CreatedAt(); !ok {
+		if batchmsg.DefaultCreatedAt == nil {
+			return fmt.Errorf("ent: uninitialized batchmsg.DefaultCreatedAt (forgotten import ent/runtime?)")
+		}
+		v := batchmsg.DefaultCreatedAt()
+		bmc.mutation.SetCreatedAt(v)
+	}
+	if _, ok := bmc.mutation.UpdatedAt(); !ok {
+		if batchmsg.DefaultUpdatedAt == nil {
+			return fmt.Errorf("ent: uninitialized batchmsg.DefaultUpdatedAt (forgotten import ent/runtime?)")
+		}
+		v := batchmsg.DefaultUpdatedAt()
+		bmc.mutation.SetUpdatedAt(v)
+	}
+	return nil
+}
+
+// check runs all checks and user-defined validators on the builder.
+func (bmc *BatchMsgCreate) check() error {
+	if _, ok := bmc.mutation.CreatedAt(); !ok {
+		return &ValidationError{Name: "created_at", err: errors.New(`ent: missing required field "BatchMsg.created_at"`)}
+	}
+	if _, ok := bmc.mutation.UpdatedAt(); !ok {
+		return &ValidationError{Name: "updated_at", err: errors.New(`ent: missing required field "BatchMsg.updated_at"`)}
+	}
+	return nil
+}
+
+func (bmc *BatchMsgCreate) sqlSave(ctx context.Context) (*BatchMsg, error) {
+	if err := bmc.check(); err != nil {
+		return nil, err
+	}
+	_node, _spec := bmc.createSpec()
+	if err := sqlgraph.CreateNode(ctx, bmc.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)
+	}
+	bmc.mutation.id = &_node.ID
+	bmc.mutation.done = true
+	return _node, nil
+}
+
+func (bmc *BatchMsgCreate) createSpec() (*BatchMsg, *sqlgraph.CreateSpec) {
+	var (
+		_node = &BatchMsg{config: bmc.config}
+		_spec = sqlgraph.NewCreateSpec(batchmsg.Table, sqlgraph.NewFieldSpec(batchmsg.FieldID, field.TypeUint64))
+	)
+	_spec.OnConflict = bmc.conflict
+	if id, ok := bmc.mutation.ID(); ok {
+		_node.ID = id
+		_spec.ID.Value = id
+	}
+	if value, ok := bmc.mutation.CreatedAt(); ok {
+		_spec.SetField(batchmsg.FieldCreatedAt, field.TypeTime, value)
+		_node.CreatedAt = value
+	}
+	if value, ok := bmc.mutation.UpdatedAt(); ok {
+		_spec.SetField(batchmsg.FieldUpdatedAt, field.TypeTime, value)
+		_node.UpdatedAt = value
+	}
+	if value, ok := bmc.mutation.DeletedAt(); ok {
+		_spec.SetField(batchmsg.FieldDeletedAt, field.TypeTime, value)
+		_node.DeletedAt = value
+	}
+	if value, ok := bmc.mutation.Status(); ok {
+		_spec.SetField(batchmsg.FieldStatus, field.TypeUint8, value)
+		_node.Status = value
+	}
+	if value, ok := bmc.mutation.BatchNo(); ok {
+		_spec.SetField(batchmsg.FieldBatchNo, field.TypeString, value)
+		_node.BatchNo = value
+	}
+	if value, ok := bmc.mutation.Fromwxid(); ok {
+		_spec.SetField(batchmsg.FieldFromwxid, field.TypeString, value)
+		_node.Fromwxid = value
+	}
+	if value, ok := bmc.mutation.Msg(); ok {
+		_spec.SetField(batchmsg.FieldMsg, field.TypeString, value)
+		_node.Msg = value
+	}
+	if value, ok := bmc.mutation.Tag(); ok {
+		_spec.SetField(batchmsg.FieldTag, field.TypeString, value)
+		_node.Tag = value
+	}
+	if value, ok := bmc.mutation.Total(); ok {
+		_spec.SetField(batchmsg.FieldTotal, field.TypeInt32, value)
+		_node.Total = value
+	}
+	if value, ok := bmc.mutation.Success(); ok {
+		_spec.SetField(batchmsg.FieldSuccess, field.TypeInt32, value)
+		_node.Success = value
+	}
+	if value, ok := bmc.mutation.Fail(); ok {
+		_spec.SetField(batchmsg.FieldFail, field.TypeInt32, value)
+		_node.Fail = value
+	}
+	if value, ok := bmc.mutation.StartTime(); ok {
+		_spec.SetField(batchmsg.FieldStartTime, field.TypeTime, value)
+		_node.StartTime = value
+	}
+	if value, ok := bmc.mutation.StopTime(); ok {
+		_spec.SetField(batchmsg.FieldStopTime, field.TypeTime, value)
+		_node.StopTime = value
+	}
+	return _node, _spec
+}
+
+// OnConflict allows configuring the `ON CONFLICT` / `ON DUPLICATE KEY` clause
+// of the `INSERT` statement. For example:
+//
+//	client.BatchMsg.Create().
+//		SetCreatedAt(v).
+//		OnConflict(
+//			// Update the row with the new values
+//			// the was proposed for insertion.
+//			sql.ResolveWithNewValues(),
+//		).
+//		// Override some of the fields with custom
+//		// update values.
+//		Update(func(u *ent.BatchMsgUpsert) {
+//			SetCreatedAt(v+v).
+//		}).
+//		Exec(ctx)
+func (bmc *BatchMsgCreate) OnConflict(opts ...sql.ConflictOption) *BatchMsgUpsertOne {
+	bmc.conflict = opts
+	return &BatchMsgUpsertOne{
+		create: bmc,
+	}
+}
+
+// OnConflictColumns calls `OnConflict` and configures the columns
+// as conflict target. Using this option is equivalent to using:
+//
+//	client.BatchMsg.Create().
+//		OnConflict(sql.ConflictColumns(columns...)).
+//		Exec(ctx)
+func (bmc *BatchMsgCreate) OnConflictColumns(columns ...string) *BatchMsgUpsertOne {
+	bmc.conflict = append(bmc.conflict, sql.ConflictColumns(columns...))
+	return &BatchMsgUpsertOne{
+		create: bmc,
+	}
+}
+
+type (
+	// BatchMsgUpsertOne is the builder for "upsert"-ing
+	//  one BatchMsg node.
+	BatchMsgUpsertOne struct {
+		create *BatchMsgCreate
+	}
+
+	// BatchMsgUpsert is the "OnConflict" setter.
+	BatchMsgUpsert struct {
+		*sql.UpdateSet
+	}
+)
+
+// SetUpdatedAt sets the "updated_at" field.
+func (u *BatchMsgUpsert) SetUpdatedAt(v time.Time) *BatchMsgUpsert {
+	u.Set(batchmsg.FieldUpdatedAt, v)
+	return u
+}
+
+// UpdateUpdatedAt sets the "updated_at" field to the value that was provided on create.
+func (u *BatchMsgUpsert) UpdateUpdatedAt() *BatchMsgUpsert {
+	u.SetExcluded(batchmsg.FieldUpdatedAt)
+	return u
+}
+
+// SetDeletedAt sets the "deleted_at" field.
+func (u *BatchMsgUpsert) SetDeletedAt(v time.Time) *BatchMsgUpsert {
+	u.Set(batchmsg.FieldDeletedAt, v)
+	return u
+}
+
+// UpdateDeletedAt sets the "deleted_at" field to the value that was provided on create.
+func (u *BatchMsgUpsert) UpdateDeletedAt() *BatchMsgUpsert {
+	u.SetExcluded(batchmsg.FieldDeletedAt)
+	return u
+}
+
+// ClearDeletedAt clears the value of the "deleted_at" field.
+func (u *BatchMsgUpsert) ClearDeletedAt() *BatchMsgUpsert {
+	u.SetNull(batchmsg.FieldDeletedAt)
+	return u
+}
+
+// SetStatus sets the "status" field.
+func (u *BatchMsgUpsert) SetStatus(v uint8) *BatchMsgUpsert {
+	u.Set(batchmsg.FieldStatus, v)
+	return u
+}
+
+// UpdateStatus sets the "status" field to the value that was provided on create.
+func (u *BatchMsgUpsert) UpdateStatus() *BatchMsgUpsert {
+	u.SetExcluded(batchmsg.FieldStatus)
+	return u
+}
+
+// AddStatus adds v to the "status" field.
+func (u *BatchMsgUpsert) AddStatus(v uint8) *BatchMsgUpsert {
+	u.Add(batchmsg.FieldStatus, v)
+	return u
+}
+
+// ClearStatus clears the value of the "status" field.
+func (u *BatchMsgUpsert) ClearStatus() *BatchMsgUpsert {
+	u.SetNull(batchmsg.FieldStatus)
+	return u
+}
+
+// SetBatchNo sets the "batch_no" field.
+func (u *BatchMsgUpsert) SetBatchNo(v string) *BatchMsgUpsert {
+	u.Set(batchmsg.FieldBatchNo, v)
+	return u
+}
+
+// UpdateBatchNo sets the "batch_no" field to the value that was provided on create.
+func (u *BatchMsgUpsert) UpdateBatchNo() *BatchMsgUpsert {
+	u.SetExcluded(batchmsg.FieldBatchNo)
+	return u
+}
+
+// ClearBatchNo clears the value of the "batch_no" field.
+func (u *BatchMsgUpsert) ClearBatchNo() *BatchMsgUpsert {
+	u.SetNull(batchmsg.FieldBatchNo)
+	return u
+}
+
+// SetFromwxid sets the "fromwxid" field.
+func (u *BatchMsgUpsert) SetFromwxid(v string) *BatchMsgUpsert {
+	u.Set(batchmsg.FieldFromwxid, v)
+	return u
+}
+
+// UpdateFromwxid sets the "fromwxid" field to the value that was provided on create.
+func (u *BatchMsgUpsert) UpdateFromwxid() *BatchMsgUpsert {
+	u.SetExcluded(batchmsg.FieldFromwxid)
+	return u
+}
+
+// ClearFromwxid clears the value of the "fromwxid" field.
+func (u *BatchMsgUpsert) ClearFromwxid() *BatchMsgUpsert {
+	u.SetNull(batchmsg.FieldFromwxid)
+	return u
+}
+
+// SetMsg sets the "msg" field.
+func (u *BatchMsgUpsert) SetMsg(v string) *BatchMsgUpsert {
+	u.Set(batchmsg.FieldMsg, v)
+	return u
+}
+
+// UpdateMsg sets the "msg" field to the value that was provided on create.
+func (u *BatchMsgUpsert) UpdateMsg() *BatchMsgUpsert {
+	u.SetExcluded(batchmsg.FieldMsg)
+	return u
+}
+
+// ClearMsg clears the value of the "msg" field.
+func (u *BatchMsgUpsert) ClearMsg() *BatchMsgUpsert {
+	u.SetNull(batchmsg.FieldMsg)
+	return u
+}
+
+// SetTag sets the "tag" field.
+func (u *BatchMsgUpsert) SetTag(v string) *BatchMsgUpsert {
+	u.Set(batchmsg.FieldTag, v)
+	return u
+}
+
+// UpdateTag sets the "tag" field to the value that was provided on create.
+func (u *BatchMsgUpsert) UpdateTag() *BatchMsgUpsert {
+	u.SetExcluded(batchmsg.FieldTag)
+	return u
+}
+
+// ClearTag clears the value of the "tag" field.
+func (u *BatchMsgUpsert) ClearTag() *BatchMsgUpsert {
+	u.SetNull(batchmsg.FieldTag)
+	return u
+}
+
+// SetTotal sets the "total" field.
+func (u *BatchMsgUpsert) SetTotal(v int32) *BatchMsgUpsert {
+	u.Set(batchmsg.FieldTotal, v)
+	return u
+}
+
+// UpdateTotal sets the "total" field to the value that was provided on create.
+func (u *BatchMsgUpsert) UpdateTotal() *BatchMsgUpsert {
+	u.SetExcluded(batchmsg.FieldTotal)
+	return u
+}
+
+// AddTotal adds v to the "total" field.
+func (u *BatchMsgUpsert) AddTotal(v int32) *BatchMsgUpsert {
+	u.Add(batchmsg.FieldTotal, v)
+	return u
+}
+
+// ClearTotal clears the value of the "total" field.
+func (u *BatchMsgUpsert) ClearTotal() *BatchMsgUpsert {
+	u.SetNull(batchmsg.FieldTotal)
+	return u
+}
+
+// SetSuccess sets the "success" field.
+func (u *BatchMsgUpsert) SetSuccess(v int32) *BatchMsgUpsert {
+	u.Set(batchmsg.FieldSuccess, v)
+	return u
+}
+
+// UpdateSuccess sets the "success" field to the value that was provided on create.
+func (u *BatchMsgUpsert) UpdateSuccess() *BatchMsgUpsert {
+	u.SetExcluded(batchmsg.FieldSuccess)
+	return u
+}
+
+// AddSuccess adds v to the "success" field.
+func (u *BatchMsgUpsert) AddSuccess(v int32) *BatchMsgUpsert {
+	u.Add(batchmsg.FieldSuccess, v)
+	return u
+}
+
+// ClearSuccess clears the value of the "success" field.
+func (u *BatchMsgUpsert) ClearSuccess() *BatchMsgUpsert {
+	u.SetNull(batchmsg.FieldSuccess)
+	return u
+}
+
+// SetFail sets the "fail" field.
+func (u *BatchMsgUpsert) SetFail(v int32) *BatchMsgUpsert {
+	u.Set(batchmsg.FieldFail, v)
+	return u
+}
+
+// UpdateFail sets the "fail" field to the value that was provided on create.
+func (u *BatchMsgUpsert) UpdateFail() *BatchMsgUpsert {
+	u.SetExcluded(batchmsg.FieldFail)
+	return u
+}
+
+// AddFail adds v to the "fail" field.
+func (u *BatchMsgUpsert) AddFail(v int32) *BatchMsgUpsert {
+	u.Add(batchmsg.FieldFail, v)
+	return u
+}
+
+// ClearFail clears the value of the "fail" field.
+func (u *BatchMsgUpsert) ClearFail() *BatchMsgUpsert {
+	u.SetNull(batchmsg.FieldFail)
+	return u
+}
+
+// SetStartTime sets the "start_time" field.
+func (u *BatchMsgUpsert) SetStartTime(v time.Time) *BatchMsgUpsert {
+	u.Set(batchmsg.FieldStartTime, v)
+	return u
+}
+
+// UpdateStartTime sets the "start_time" field to the value that was provided on create.
+func (u *BatchMsgUpsert) UpdateStartTime() *BatchMsgUpsert {
+	u.SetExcluded(batchmsg.FieldStartTime)
+	return u
+}
+
+// ClearStartTime clears the value of the "start_time" field.
+func (u *BatchMsgUpsert) ClearStartTime() *BatchMsgUpsert {
+	u.SetNull(batchmsg.FieldStartTime)
+	return u
+}
+
+// SetStopTime sets the "stop_time" field.
+func (u *BatchMsgUpsert) SetStopTime(v time.Time) *BatchMsgUpsert {
+	u.Set(batchmsg.FieldStopTime, v)
+	return u
+}
+
+// UpdateStopTime sets the "stop_time" field to the value that was provided on create.
+func (u *BatchMsgUpsert) UpdateStopTime() *BatchMsgUpsert {
+	u.SetExcluded(batchmsg.FieldStopTime)
+	return u
+}
+
+// ClearStopTime clears the value of the "stop_time" field.
+func (u *BatchMsgUpsert) ClearStopTime() *BatchMsgUpsert {
+	u.SetNull(batchmsg.FieldStopTime)
+	return u
+}
+
+// UpdateNewValues updates the mutable fields using the new values that were set on create except the ID field.
+// Using this option is equivalent to using:
+//
+//	client.BatchMsg.Create().
+//		OnConflict(
+//			sql.ResolveWithNewValues(),
+//			sql.ResolveWith(func(u *sql.UpdateSet) {
+//				u.SetIgnore(batchmsg.FieldID)
+//			}),
+//		).
+//		Exec(ctx)
+func (u *BatchMsgUpsertOne) UpdateNewValues() *BatchMsgUpsertOne {
+	u.create.conflict = append(u.create.conflict, sql.ResolveWithNewValues())
+	u.create.conflict = append(u.create.conflict, sql.ResolveWith(func(s *sql.UpdateSet) {
+		if _, exists := u.create.mutation.ID(); exists {
+			s.SetIgnore(batchmsg.FieldID)
+		}
+		if _, exists := u.create.mutation.CreatedAt(); exists {
+			s.SetIgnore(batchmsg.FieldCreatedAt)
+		}
+	}))
+	return u
+}
+
+// Ignore sets each column to itself in case of conflict.
+// Using this option is equivalent to using:
+//
+//	client.BatchMsg.Create().
+//	    OnConflict(sql.ResolveWithIgnore()).
+//	    Exec(ctx)
+func (u *BatchMsgUpsertOne) Ignore() *BatchMsgUpsertOne {
+	u.create.conflict = append(u.create.conflict, sql.ResolveWithIgnore())
+	return u
+}
+
+// DoNothing configures the conflict_action to `DO NOTHING`.
+// Supported only by SQLite and PostgreSQL.
+func (u *BatchMsgUpsertOne) DoNothing() *BatchMsgUpsertOne {
+	u.create.conflict = append(u.create.conflict, sql.DoNothing())
+	return u
+}
+
+// Update allows overriding fields `UPDATE` values. See the BatchMsgCreate.OnConflict
+// documentation for more info.
+func (u *BatchMsgUpsertOne) Update(set func(*BatchMsgUpsert)) *BatchMsgUpsertOne {
+	u.create.conflict = append(u.create.conflict, sql.ResolveWith(func(update *sql.UpdateSet) {
+		set(&BatchMsgUpsert{UpdateSet: update})
+	}))
+	return u
+}
+
+// SetUpdatedAt sets the "updated_at" field.
+func (u *BatchMsgUpsertOne) SetUpdatedAt(v time.Time) *BatchMsgUpsertOne {
+	return u.Update(func(s *BatchMsgUpsert) {
+		s.SetUpdatedAt(v)
+	})
+}
+
+// UpdateUpdatedAt sets the "updated_at" field to the value that was provided on create.
+func (u *BatchMsgUpsertOne) UpdateUpdatedAt() *BatchMsgUpsertOne {
+	return u.Update(func(s *BatchMsgUpsert) {
+		s.UpdateUpdatedAt()
+	})
+}
+
+// SetDeletedAt sets the "deleted_at" field.
+func (u *BatchMsgUpsertOne) SetDeletedAt(v time.Time) *BatchMsgUpsertOne {
+	return u.Update(func(s *BatchMsgUpsert) {
+		s.SetDeletedAt(v)
+	})
+}
+
+// UpdateDeletedAt sets the "deleted_at" field to the value that was provided on create.
+func (u *BatchMsgUpsertOne) UpdateDeletedAt() *BatchMsgUpsertOne {
+	return u.Update(func(s *BatchMsgUpsert) {
+		s.UpdateDeletedAt()
+	})
+}
+
+// ClearDeletedAt clears the value of the "deleted_at" field.
+func (u *BatchMsgUpsertOne) ClearDeletedAt() *BatchMsgUpsertOne {
+	return u.Update(func(s *BatchMsgUpsert) {
+		s.ClearDeletedAt()
+	})
+}
+
+// SetStatus sets the "status" field.
+func (u *BatchMsgUpsertOne) SetStatus(v uint8) *BatchMsgUpsertOne {
+	return u.Update(func(s *BatchMsgUpsert) {
+		s.SetStatus(v)
+	})
+}
+
+// AddStatus adds v to the "status" field.
+func (u *BatchMsgUpsertOne) AddStatus(v uint8) *BatchMsgUpsertOne {
+	return u.Update(func(s *BatchMsgUpsert) {
+		s.AddStatus(v)
+	})
+}
+
+// UpdateStatus sets the "status" field to the value that was provided on create.
+func (u *BatchMsgUpsertOne) UpdateStatus() *BatchMsgUpsertOne {
+	return u.Update(func(s *BatchMsgUpsert) {
+		s.UpdateStatus()
+	})
+}
+
+// ClearStatus clears the value of the "status" field.
+func (u *BatchMsgUpsertOne) ClearStatus() *BatchMsgUpsertOne {
+	return u.Update(func(s *BatchMsgUpsert) {
+		s.ClearStatus()
+	})
+}
+
+// SetBatchNo sets the "batch_no" field.
+func (u *BatchMsgUpsertOne) SetBatchNo(v string) *BatchMsgUpsertOne {
+	return u.Update(func(s *BatchMsgUpsert) {
+		s.SetBatchNo(v)
+	})
+}
+
+// UpdateBatchNo sets the "batch_no" field to the value that was provided on create.
+func (u *BatchMsgUpsertOne) UpdateBatchNo() *BatchMsgUpsertOne {
+	return u.Update(func(s *BatchMsgUpsert) {
+		s.UpdateBatchNo()
+	})
+}
+
+// ClearBatchNo clears the value of the "batch_no" field.
+func (u *BatchMsgUpsertOne) ClearBatchNo() *BatchMsgUpsertOne {
+	return u.Update(func(s *BatchMsgUpsert) {
+		s.ClearBatchNo()
+	})
+}
+
+// SetFromwxid sets the "fromwxid" field.
+func (u *BatchMsgUpsertOne) SetFromwxid(v string) *BatchMsgUpsertOne {
+	return u.Update(func(s *BatchMsgUpsert) {
+		s.SetFromwxid(v)
+	})
+}
+
+// UpdateFromwxid sets the "fromwxid" field to the value that was provided on create.
+func (u *BatchMsgUpsertOne) UpdateFromwxid() *BatchMsgUpsertOne {
+	return u.Update(func(s *BatchMsgUpsert) {
+		s.UpdateFromwxid()
+	})
+}
+
+// ClearFromwxid clears the value of the "fromwxid" field.
+func (u *BatchMsgUpsertOne) ClearFromwxid() *BatchMsgUpsertOne {
+	return u.Update(func(s *BatchMsgUpsert) {
+		s.ClearFromwxid()
+	})
+}
+
+// SetMsg sets the "msg" field.
+func (u *BatchMsgUpsertOne) SetMsg(v string) *BatchMsgUpsertOne {
+	return u.Update(func(s *BatchMsgUpsert) {
+		s.SetMsg(v)
+	})
+}
+
+// UpdateMsg sets the "msg" field to the value that was provided on create.
+func (u *BatchMsgUpsertOne) UpdateMsg() *BatchMsgUpsertOne {
+	return u.Update(func(s *BatchMsgUpsert) {
+		s.UpdateMsg()
+	})
+}
+
+// ClearMsg clears the value of the "msg" field.
+func (u *BatchMsgUpsertOne) ClearMsg() *BatchMsgUpsertOne {
+	return u.Update(func(s *BatchMsgUpsert) {
+		s.ClearMsg()
+	})
+}
+
+// SetTag sets the "tag" field.
+func (u *BatchMsgUpsertOne) SetTag(v string) *BatchMsgUpsertOne {
+	return u.Update(func(s *BatchMsgUpsert) {
+		s.SetTag(v)
+	})
+}
+
+// UpdateTag sets the "tag" field to the value that was provided on create.
+func (u *BatchMsgUpsertOne) UpdateTag() *BatchMsgUpsertOne {
+	return u.Update(func(s *BatchMsgUpsert) {
+		s.UpdateTag()
+	})
+}
+
+// ClearTag clears the value of the "tag" field.
+func (u *BatchMsgUpsertOne) ClearTag() *BatchMsgUpsertOne {
+	return u.Update(func(s *BatchMsgUpsert) {
+		s.ClearTag()
+	})
+}
+
+// SetTotal sets the "total" field.
+func (u *BatchMsgUpsertOne) SetTotal(v int32) *BatchMsgUpsertOne {
+	return u.Update(func(s *BatchMsgUpsert) {
+		s.SetTotal(v)
+	})
+}
+
+// AddTotal adds v to the "total" field.
+func (u *BatchMsgUpsertOne) AddTotal(v int32) *BatchMsgUpsertOne {
+	return u.Update(func(s *BatchMsgUpsert) {
+		s.AddTotal(v)
+	})
+}
+
+// UpdateTotal sets the "total" field to the value that was provided on create.
+func (u *BatchMsgUpsertOne) UpdateTotal() *BatchMsgUpsertOne {
+	return u.Update(func(s *BatchMsgUpsert) {
+		s.UpdateTotal()
+	})
+}
+
+// ClearTotal clears the value of the "total" field.
+func (u *BatchMsgUpsertOne) ClearTotal() *BatchMsgUpsertOne {
+	return u.Update(func(s *BatchMsgUpsert) {
+		s.ClearTotal()
+	})
+}
+
+// SetSuccess sets the "success" field.
+func (u *BatchMsgUpsertOne) SetSuccess(v int32) *BatchMsgUpsertOne {
+	return u.Update(func(s *BatchMsgUpsert) {
+		s.SetSuccess(v)
+	})
+}
+
+// AddSuccess adds v to the "success" field.
+func (u *BatchMsgUpsertOne) AddSuccess(v int32) *BatchMsgUpsertOne {
+	return u.Update(func(s *BatchMsgUpsert) {
+		s.AddSuccess(v)
+	})
+}
+
+// UpdateSuccess sets the "success" field to the value that was provided on create.
+func (u *BatchMsgUpsertOne) UpdateSuccess() *BatchMsgUpsertOne {
+	return u.Update(func(s *BatchMsgUpsert) {
+		s.UpdateSuccess()
+	})
+}
+
+// ClearSuccess clears the value of the "success" field.
+func (u *BatchMsgUpsertOne) ClearSuccess() *BatchMsgUpsertOne {
+	return u.Update(func(s *BatchMsgUpsert) {
+		s.ClearSuccess()
+	})
+}
+
+// SetFail sets the "fail" field.
+func (u *BatchMsgUpsertOne) SetFail(v int32) *BatchMsgUpsertOne {
+	return u.Update(func(s *BatchMsgUpsert) {
+		s.SetFail(v)
+	})
+}
+
+// AddFail adds v to the "fail" field.
+func (u *BatchMsgUpsertOne) AddFail(v int32) *BatchMsgUpsertOne {
+	return u.Update(func(s *BatchMsgUpsert) {
+		s.AddFail(v)
+	})
+}
+
+// UpdateFail sets the "fail" field to the value that was provided on create.
+func (u *BatchMsgUpsertOne) UpdateFail() *BatchMsgUpsertOne {
+	return u.Update(func(s *BatchMsgUpsert) {
+		s.UpdateFail()
+	})
+}
+
+// ClearFail clears the value of the "fail" field.
+func (u *BatchMsgUpsertOne) ClearFail() *BatchMsgUpsertOne {
+	return u.Update(func(s *BatchMsgUpsert) {
+		s.ClearFail()
+	})
+}
+
+// SetStartTime sets the "start_time" field.
+func (u *BatchMsgUpsertOne) SetStartTime(v time.Time) *BatchMsgUpsertOne {
+	return u.Update(func(s *BatchMsgUpsert) {
+		s.SetStartTime(v)
+	})
+}
+
+// UpdateStartTime sets the "start_time" field to the value that was provided on create.
+func (u *BatchMsgUpsertOne) UpdateStartTime() *BatchMsgUpsertOne {
+	return u.Update(func(s *BatchMsgUpsert) {
+		s.UpdateStartTime()
+	})
+}
+
+// ClearStartTime clears the value of the "start_time" field.
+func (u *BatchMsgUpsertOne) ClearStartTime() *BatchMsgUpsertOne {
+	return u.Update(func(s *BatchMsgUpsert) {
+		s.ClearStartTime()
+	})
+}
+
+// SetStopTime sets the "stop_time" field.
+func (u *BatchMsgUpsertOne) SetStopTime(v time.Time) *BatchMsgUpsertOne {
+	return u.Update(func(s *BatchMsgUpsert) {
+		s.SetStopTime(v)
+	})
+}
+
+// UpdateStopTime sets the "stop_time" field to the value that was provided on create.
+func (u *BatchMsgUpsertOne) UpdateStopTime() *BatchMsgUpsertOne {
+	return u.Update(func(s *BatchMsgUpsert) {
+		s.UpdateStopTime()
+	})
+}
+
+// ClearStopTime clears the value of the "stop_time" field.
+func (u *BatchMsgUpsertOne) ClearStopTime() *BatchMsgUpsertOne {
+	return u.Update(func(s *BatchMsgUpsert) {
+		s.ClearStopTime()
+	})
+}
+
+// Exec executes the query.
+func (u *BatchMsgUpsertOne) Exec(ctx context.Context) error {
+	if len(u.create.conflict) == 0 {
+		return errors.New("ent: missing options for BatchMsgCreate.OnConflict")
+	}
+	return u.create.Exec(ctx)
+}
+
+// ExecX is like Exec, but panics if an error occurs.
+func (u *BatchMsgUpsertOne) ExecX(ctx context.Context) {
+	if err := u.create.Exec(ctx); err != nil {
+		panic(err)
+	}
+}
+
+// Exec executes the UPSERT query and returns the inserted/updated ID.
+func (u *BatchMsgUpsertOne) ID(ctx context.Context) (id uint64, err error) {
+	node, err := u.create.Save(ctx)
+	if err != nil {
+		return id, err
+	}
+	return node.ID, nil
+}
+
+// IDX is like ID, but panics if an error occurs.
+func (u *BatchMsgUpsertOne) IDX(ctx context.Context) uint64 {
+	id, err := u.ID(ctx)
+	if err != nil {
+		panic(err)
+	}
+	return id
+}
+
+// BatchMsgCreateBulk is the builder for creating many BatchMsg entities in bulk.
+type BatchMsgCreateBulk struct {
+	config
+	err      error
+	builders []*BatchMsgCreate
+	conflict []sql.ConflictOption
+}
+
+// Save creates the BatchMsg entities in the database.
+func (bmcb *BatchMsgCreateBulk) Save(ctx context.Context) ([]*BatchMsg, error) {
+	if bmcb.err != nil {
+		return nil, bmcb.err
+	}
+	specs := make([]*sqlgraph.CreateSpec, len(bmcb.builders))
+	nodes := make([]*BatchMsg, len(bmcb.builders))
+	mutators := make([]Mutator, len(bmcb.builders))
+	for i := range bmcb.builders {
+		func(i int, root context.Context) {
+			builder := bmcb.builders[i]
+			builder.defaults()
+			var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) {
+				mutation, ok := m.(*BatchMsgMutation)
+				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, bmcb.builders[i+1].mutation)
+				} else {
+					spec := &sqlgraph.BatchCreateSpec{Nodes: specs}
+					spec.OnConflict = bmcb.conflict
+					// Invoke the actual operation on the latest mutation in the chain.
+					if err = sqlgraph.BatchCreate(ctx, bmcb.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, bmcb.builders[0].mutation); err != nil {
+			return nil, err
+		}
+	}
+	return nodes, nil
+}
+
+// SaveX is like Save, but panics if an error occurs.
+func (bmcb *BatchMsgCreateBulk) SaveX(ctx context.Context) []*BatchMsg {
+	v, err := bmcb.Save(ctx)
+	if err != nil {
+		panic(err)
+	}
+	return v
+}
+
+// Exec executes the query.
+func (bmcb *BatchMsgCreateBulk) Exec(ctx context.Context) error {
+	_, err := bmcb.Save(ctx)
+	return err
+}
+
+// ExecX is like Exec, but panics if an error occurs.
+func (bmcb *BatchMsgCreateBulk) ExecX(ctx context.Context) {
+	if err := bmcb.Exec(ctx); err != nil {
+		panic(err)
+	}
+}
+
+// OnConflict allows configuring the `ON CONFLICT` / `ON DUPLICATE KEY` clause
+// of the `INSERT` statement. For example:
+//
+//	client.BatchMsg.CreateBulk(builders...).
+//		OnConflict(
+//			// Update the row with the new values
+//			// the was proposed for insertion.
+//			sql.ResolveWithNewValues(),
+//		).
+//		// Override some of the fields with custom
+//		// update values.
+//		Update(func(u *ent.BatchMsgUpsert) {
+//			SetCreatedAt(v+v).
+//		}).
+//		Exec(ctx)
+func (bmcb *BatchMsgCreateBulk) OnConflict(opts ...sql.ConflictOption) *BatchMsgUpsertBulk {
+	bmcb.conflict = opts
+	return &BatchMsgUpsertBulk{
+		create: bmcb,
+	}
+}
+
+// OnConflictColumns calls `OnConflict` and configures the columns
+// as conflict target. Using this option is equivalent to using:
+//
+//	client.BatchMsg.Create().
+//		OnConflict(sql.ConflictColumns(columns...)).
+//		Exec(ctx)
+func (bmcb *BatchMsgCreateBulk) OnConflictColumns(columns ...string) *BatchMsgUpsertBulk {
+	bmcb.conflict = append(bmcb.conflict, sql.ConflictColumns(columns...))
+	return &BatchMsgUpsertBulk{
+		create: bmcb,
+	}
+}
+
+// BatchMsgUpsertBulk is the builder for "upsert"-ing
+// a bulk of BatchMsg nodes.
+type BatchMsgUpsertBulk struct {
+	create *BatchMsgCreateBulk
+}
+
+// UpdateNewValues updates the mutable fields using the new values that
+// were set on create. Using this option is equivalent to using:
+//
+//	client.BatchMsg.Create().
+//		OnConflict(
+//			sql.ResolveWithNewValues(),
+//			sql.ResolveWith(func(u *sql.UpdateSet) {
+//				u.SetIgnore(batchmsg.FieldID)
+//			}),
+//		).
+//		Exec(ctx)
+func (u *BatchMsgUpsertBulk) UpdateNewValues() *BatchMsgUpsertBulk {
+	u.create.conflict = append(u.create.conflict, sql.ResolveWithNewValues())
+	u.create.conflict = append(u.create.conflict, sql.ResolveWith(func(s *sql.UpdateSet) {
+		for _, b := range u.create.builders {
+			if _, exists := b.mutation.ID(); exists {
+				s.SetIgnore(batchmsg.FieldID)
+			}
+			if _, exists := b.mutation.CreatedAt(); exists {
+				s.SetIgnore(batchmsg.FieldCreatedAt)
+			}
+		}
+	}))
+	return u
+}
+
+// Ignore sets each column to itself in case of conflict.
+// Using this option is equivalent to using:
+//
+//	client.BatchMsg.Create().
+//		OnConflict(sql.ResolveWithIgnore()).
+//		Exec(ctx)
+func (u *BatchMsgUpsertBulk) Ignore() *BatchMsgUpsertBulk {
+	u.create.conflict = append(u.create.conflict, sql.ResolveWithIgnore())
+	return u
+}
+
+// DoNothing configures the conflict_action to `DO NOTHING`.
+// Supported only by SQLite and PostgreSQL.
+func (u *BatchMsgUpsertBulk) DoNothing() *BatchMsgUpsertBulk {
+	u.create.conflict = append(u.create.conflict, sql.DoNothing())
+	return u
+}
+
+// Update allows overriding fields `UPDATE` values. See the BatchMsgCreateBulk.OnConflict
+// documentation for more info.
+func (u *BatchMsgUpsertBulk) Update(set func(*BatchMsgUpsert)) *BatchMsgUpsertBulk {
+	u.create.conflict = append(u.create.conflict, sql.ResolveWith(func(update *sql.UpdateSet) {
+		set(&BatchMsgUpsert{UpdateSet: update})
+	}))
+	return u
+}
+
+// SetUpdatedAt sets the "updated_at" field.
+func (u *BatchMsgUpsertBulk) SetUpdatedAt(v time.Time) *BatchMsgUpsertBulk {
+	return u.Update(func(s *BatchMsgUpsert) {
+		s.SetUpdatedAt(v)
+	})
+}
+
+// UpdateUpdatedAt sets the "updated_at" field to the value that was provided on create.
+func (u *BatchMsgUpsertBulk) UpdateUpdatedAt() *BatchMsgUpsertBulk {
+	return u.Update(func(s *BatchMsgUpsert) {
+		s.UpdateUpdatedAt()
+	})
+}
+
+// SetDeletedAt sets the "deleted_at" field.
+func (u *BatchMsgUpsertBulk) SetDeletedAt(v time.Time) *BatchMsgUpsertBulk {
+	return u.Update(func(s *BatchMsgUpsert) {
+		s.SetDeletedAt(v)
+	})
+}
+
+// UpdateDeletedAt sets the "deleted_at" field to the value that was provided on create.
+func (u *BatchMsgUpsertBulk) UpdateDeletedAt() *BatchMsgUpsertBulk {
+	return u.Update(func(s *BatchMsgUpsert) {
+		s.UpdateDeletedAt()
+	})
+}
+
+// ClearDeletedAt clears the value of the "deleted_at" field.
+func (u *BatchMsgUpsertBulk) ClearDeletedAt() *BatchMsgUpsertBulk {
+	return u.Update(func(s *BatchMsgUpsert) {
+		s.ClearDeletedAt()
+	})
+}
+
+// SetStatus sets the "status" field.
+func (u *BatchMsgUpsertBulk) SetStatus(v uint8) *BatchMsgUpsertBulk {
+	return u.Update(func(s *BatchMsgUpsert) {
+		s.SetStatus(v)
+	})
+}
+
+// AddStatus adds v to the "status" field.
+func (u *BatchMsgUpsertBulk) AddStatus(v uint8) *BatchMsgUpsertBulk {
+	return u.Update(func(s *BatchMsgUpsert) {
+		s.AddStatus(v)
+	})
+}
+
+// UpdateStatus sets the "status" field to the value that was provided on create.
+func (u *BatchMsgUpsertBulk) UpdateStatus() *BatchMsgUpsertBulk {
+	return u.Update(func(s *BatchMsgUpsert) {
+		s.UpdateStatus()
+	})
+}
+
+// ClearStatus clears the value of the "status" field.
+func (u *BatchMsgUpsertBulk) ClearStatus() *BatchMsgUpsertBulk {
+	return u.Update(func(s *BatchMsgUpsert) {
+		s.ClearStatus()
+	})
+}
+
+// SetBatchNo sets the "batch_no" field.
+func (u *BatchMsgUpsertBulk) SetBatchNo(v string) *BatchMsgUpsertBulk {
+	return u.Update(func(s *BatchMsgUpsert) {
+		s.SetBatchNo(v)
+	})
+}
+
+// UpdateBatchNo sets the "batch_no" field to the value that was provided on create.
+func (u *BatchMsgUpsertBulk) UpdateBatchNo() *BatchMsgUpsertBulk {
+	return u.Update(func(s *BatchMsgUpsert) {
+		s.UpdateBatchNo()
+	})
+}
+
+// ClearBatchNo clears the value of the "batch_no" field.
+func (u *BatchMsgUpsertBulk) ClearBatchNo() *BatchMsgUpsertBulk {
+	return u.Update(func(s *BatchMsgUpsert) {
+		s.ClearBatchNo()
+	})
+}
+
+// SetFromwxid sets the "fromwxid" field.
+func (u *BatchMsgUpsertBulk) SetFromwxid(v string) *BatchMsgUpsertBulk {
+	return u.Update(func(s *BatchMsgUpsert) {
+		s.SetFromwxid(v)
+	})
+}
+
+// UpdateFromwxid sets the "fromwxid" field to the value that was provided on create.
+func (u *BatchMsgUpsertBulk) UpdateFromwxid() *BatchMsgUpsertBulk {
+	return u.Update(func(s *BatchMsgUpsert) {
+		s.UpdateFromwxid()
+	})
+}
+
+// ClearFromwxid clears the value of the "fromwxid" field.
+func (u *BatchMsgUpsertBulk) ClearFromwxid() *BatchMsgUpsertBulk {
+	return u.Update(func(s *BatchMsgUpsert) {
+		s.ClearFromwxid()
+	})
+}
+
+// SetMsg sets the "msg" field.
+func (u *BatchMsgUpsertBulk) SetMsg(v string) *BatchMsgUpsertBulk {
+	return u.Update(func(s *BatchMsgUpsert) {
+		s.SetMsg(v)
+	})
+}
+
+// UpdateMsg sets the "msg" field to the value that was provided on create.
+func (u *BatchMsgUpsertBulk) UpdateMsg() *BatchMsgUpsertBulk {
+	return u.Update(func(s *BatchMsgUpsert) {
+		s.UpdateMsg()
+	})
+}
+
+// ClearMsg clears the value of the "msg" field.
+func (u *BatchMsgUpsertBulk) ClearMsg() *BatchMsgUpsertBulk {
+	return u.Update(func(s *BatchMsgUpsert) {
+		s.ClearMsg()
+	})
+}
+
+// SetTag sets the "tag" field.
+func (u *BatchMsgUpsertBulk) SetTag(v string) *BatchMsgUpsertBulk {
+	return u.Update(func(s *BatchMsgUpsert) {
+		s.SetTag(v)
+	})
+}
+
+// UpdateTag sets the "tag" field to the value that was provided on create.
+func (u *BatchMsgUpsertBulk) UpdateTag() *BatchMsgUpsertBulk {
+	return u.Update(func(s *BatchMsgUpsert) {
+		s.UpdateTag()
+	})
+}
+
+// ClearTag clears the value of the "tag" field.
+func (u *BatchMsgUpsertBulk) ClearTag() *BatchMsgUpsertBulk {
+	return u.Update(func(s *BatchMsgUpsert) {
+		s.ClearTag()
+	})
+}
+
+// SetTotal sets the "total" field.
+func (u *BatchMsgUpsertBulk) SetTotal(v int32) *BatchMsgUpsertBulk {
+	return u.Update(func(s *BatchMsgUpsert) {
+		s.SetTotal(v)
+	})
+}
+
+// AddTotal adds v to the "total" field.
+func (u *BatchMsgUpsertBulk) AddTotal(v int32) *BatchMsgUpsertBulk {
+	return u.Update(func(s *BatchMsgUpsert) {
+		s.AddTotal(v)
+	})
+}
+
+// UpdateTotal sets the "total" field to the value that was provided on create.
+func (u *BatchMsgUpsertBulk) UpdateTotal() *BatchMsgUpsertBulk {
+	return u.Update(func(s *BatchMsgUpsert) {
+		s.UpdateTotal()
+	})
+}
+
+// ClearTotal clears the value of the "total" field.
+func (u *BatchMsgUpsertBulk) ClearTotal() *BatchMsgUpsertBulk {
+	return u.Update(func(s *BatchMsgUpsert) {
+		s.ClearTotal()
+	})
+}
+
+// SetSuccess sets the "success" field.
+func (u *BatchMsgUpsertBulk) SetSuccess(v int32) *BatchMsgUpsertBulk {
+	return u.Update(func(s *BatchMsgUpsert) {
+		s.SetSuccess(v)
+	})
+}
+
+// AddSuccess adds v to the "success" field.
+func (u *BatchMsgUpsertBulk) AddSuccess(v int32) *BatchMsgUpsertBulk {
+	return u.Update(func(s *BatchMsgUpsert) {
+		s.AddSuccess(v)
+	})
+}
+
+// UpdateSuccess sets the "success" field to the value that was provided on create.
+func (u *BatchMsgUpsertBulk) UpdateSuccess() *BatchMsgUpsertBulk {
+	return u.Update(func(s *BatchMsgUpsert) {
+		s.UpdateSuccess()
+	})
+}
+
+// ClearSuccess clears the value of the "success" field.
+func (u *BatchMsgUpsertBulk) ClearSuccess() *BatchMsgUpsertBulk {
+	return u.Update(func(s *BatchMsgUpsert) {
+		s.ClearSuccess()
+	})
+}
+
+// SetFail sets the "fail" field.
+func (u *BatchMsgUpsertBulk) SetFail(v int32) *BatchMsgUpsertBulk {
+	return u.Update(func(s *BatchMsgUpsert) {
+		s.SetFail(v)
+	})
+}
+
+// AddFail adds v to the "fail" field.
+func (u *BatchMsgUpsertBulk) AddFail(v int32) *BatchMsgUpsertBulk {
+	return u.Update(func(s *BatchMsgUpsert) {
+		s.AddFail(v)
+	})
+}
+
+// UpdateFail sets the "fail" field to the value that was provided on create.
+func (u *BatchMsgUpsertBulk) UpdateFail() *BatchMsgUpsertBulk {
+	return u.Update(func(s *BatchMsgUpsert) {
+		s.UpdateFail()
+	})
+}
+
+// ClearFail clears the value of the "fail" field.
+func (u *BatchMsgUpsertBulk) ClearFail() *BatchMsgUpsertBulk {
+	return u.Update(func(s *BatchMsgUpsert) {
+		s.ClearFail()
+	})
+}
+
+// SetStartTime sets the "start_time" field.
+func (u *BatchMsgUpsertBulk) SetStartTime(v time.Time) *BatchMsgUpsertBulk {
+	return u.Update(func(s *BatchMsgUpsert) {
+		s.SetStartTime(v)
+	})
+}
+
+// UpdateStartTime sets the "start_time" field to the value that was provided on create.
+func (u *BatchMsgUpsertBulk) UpdateStartTime() *BatchMsgUpsertBulk {
+	return u.Update(func(s *BatchMsgUpsert) {
+		s.UpdateStartTime()
+	})
+}
+
+// ClearStartTime clears the value of the "start_time" field.
+func (u *BatchMsgUpsertBulk) ClearStartTime() *BatchMsgUpsertBulk {
+	return u.Update(func(s *BatchMsgUpsert) {
+		s.ClearStartTime()
+	})
+}
+
+// SetStopTime sets the "stop_time" field.
+func (u *BatchMsgUpsertBulk) SetStopTime(v time.Time) *BatchMsgUpsertBulk {
+	return u.Update(func(s *BatchMsgUpsert) {
+		s.SetStopTime(v)
+	})
+}
+
+// UpdateStopTime sets the "stop_time" field to the value that was provided on create.
+func (u *BatchMsgUpsertBulk) UpdateStopTime() *BatchMsgUpsertBulk {
+	return u.Update(func(s *BatchMsgUpsert) {
+		s.UpdateStopTime()
+	})
+}
+
+// ClearStopTime clears the value of the "stop_time" field.
+func (u *BatchMsgUpsertBulk) ClearStopTime() *BatchMsgUpsertBulk {
+	return u.Update(func(s *BatchMsgUpsert) {
+		s.ClearStopTime()
+	})
+}
+
+// Exec executes the query.
+func (u *BatchMsgUpsertBulk) Exec(ctx context.Context) error {
+	if u.create.err != nil {
+		return u.create.err
+	}
+	for i, b := range u.create.builders {
+		if len(b.conflict) != 0 {
+			return fmt.Errorf("ent: OnConflict was set for builder %d. Set it on the BatchMsgCreateBulk instead", i)
+		}
+	}
+	if len(u.create.conflict) == 0 {
+		return errors.New("ent: missing options for BatchMsgCreateBulk.OnConflict")
+	}
+	return u.create.Exec(ctx)
+}
+
+// ExecX is like Exec, but panics if an error occurs.
+func (u *BatchMsgUpsertBulk) ExecX(ctx context.Context) {
+	if err := u.create.Exec(ctx); err != nil {
+		panic(err)
+	}
+}

+ 88 - 0
ent/batchmsg_delete.go

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

+ 526 - 0
ent/batchmsg_query.go

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

+ 876 - 0
ent/batchmsg_update.go

@@ -0,0 +1,876 @@
+// Code generated by ent, DO NOT EDIT.
+
+package ent
+
+import (
+	"context"
+	"errors"
+	"fmt"
+	"time"
+	"wechat-api/ent/batchmsg"
+	"wechat-api/ent/predicate"
+
+	"entgo.io/ent/dialect/sql"
+	"entgo.io/ent/dialect/sql/sqlgraph"
+	"entgo.io/ent/schema/field"
+)
+
+// BatchMsgUpdate is the builder for updating BatchMsg entities.
+type BatchMsgUpdate struct {
+	config
+	hooks    []Hook
+	mutation *BatchMsgMutation
+}
+
+// Where appends a list predicates to the BatchMsgUpdate builder.
+func (bmu *BatchMsgUpdate) Where(ps ...predicate.BatchMsg) *BatchMsgUpdate {
+	bmu.mutation.Where(ps...)
+	return bmu
+}
+
+// SetUpdatedAt sets the "updated_at" field.
+func (bmu *BatchMsgUpdate) SetUpdatedAt(t time.Time) *BatchMsgUpdate {
+	bmu.mutation.SetUpdatedAt(t)
+	return bmu
+}
+
+// SetDeletedAt sets the "deleted_at" field.
+func (bmu *BatchMsgUpdate) SetDeletedAt(t time.Time) *BatchMsgUpdate {
+	bmu.mutation.SetDeletedAt(t)
+	return bmu
+}
+
+// SetNillableDeletedAt sets the "deleted_at" field if the given value is not nil.
+func (bmu *BatchMsgUpdate) SetNillableDeletedAt(t *time.Time) *BatchMsgUpdate {
+	if t != nil {
+		bmu.SetDeletedAt(*t)
+	}
+	return bmu
+}
+
+// ClearDeletedAt clears the value of the "deleted_at" field.
+func (bmu *BatchMsgUpdate) ClearDeletedAt() *BatchMsgUpdate {
+	bmu.mutation.ClearDeletedAt()
+	return bmu
+}
+
+// SetStatus sets the "status" field.
+func (bmu *BatchMsgUpdate) SetStatus(u uint8) *BatchMsgUpdate {
+	bmu.mutation.ResetStatus()
+	bmu.mutation.SetStatus(u)
+	return bmu
+}
+
+// SetNillableStatus sets the "status" field if the given value is not nil.
+func (bmu *BatchMsgUpdate) SetNillableStatus(u *uint8) *BatchMsgUpdate {
+	if u != nil {
+		bmu.SetStatus(*u)
+	}
+	return bmu
+}
+
+// AddStatus adds u to the "status" field.
+func (bmu *BatchMsgUpdate) AddStatus(u int8) *BatchMsgUpdate {
+	bmu.mutation.AddStatus(u)
+	return bmu
+}
+
+// ClearStatus clears the value of the "status" field.
+func (bmu *BatchMsgUpdate) ClearStatus() *BatchMsgUpdate {
+	bmu.mutation.ClearStatus()
+	return bmu
+}
+
+// SetBatchNo sets the "batch_no" field.
+func (bmu *BatchMsgUpdate) SetBatchNo(s string) *BatchMsgUpdate {
+	bmu.mutation.SetBatchNo(s)
+	return bmu
+}
+
+// SetNillableBatchNo sets the "batch_no" field if the given value is not nil.
+func (bmu *BatchMsgUpdate) SetNillableBatchNo(s *string) *BatchMsgUpdate {
+	if s != nil {
+		bmu.SetBatchNo(*s)
+	}
+	return bmu
+}
+
+// ClearBatchNo clears the value of the "batch_no" field.
+func (bmu *BatchMsgUpdate) ClearBatchNo() *BatchMsgUpdate {
+	bmu.mutation.ClearBatchNo()
+	return bmu
+}
+
+// SetFromwxid sets the "fromwxid" field.
+func (bmu *BatchMsgUpdate) SetFromwxid(s string) *BatchMsgUpdate {
+	bmu.mutation.SetFromwxid(s)
+	return bmu
+}
+
+// SetNillableFromwxid sets the "fromwxid" field if the given value is not nil.
+func (bmu *BatchMsgUpdate) SetNillableFromwxid(s *string) *BatchMsgUpdate {
+	if s != nil {
+		bmu.SetFromwxid(*s)
+	}
+	return bmu
+}
+
+// ClearFromwxid clears the value of the "fromwxid" field.
+func (bmu *BatchMsgUpdate) ClearFromwxid() *BatchMsgUpdate {
+	bmu.mutation.ClearFromwxid()
+	return bmu
+}
+
+// SetMsg sets the "msg" field.
+func (bmu *BatchMsgUpdate) SetMsg(s string) *BatchMsgUpdate {
+	bmu.mutation.SetMsg(s)
+	return bmu
+}
+
+// SetNillableMsg sets the "msg" field if the given value is not nil.
+func (bmu *BatchMsgUpdate) SetNillableMsg(s *string) *BatchMsgUpdate {
+	if s != nil {
+		bmu.SetMsg(*s)
+	}
+	return bmu
+}
+
+// ClearMsg clears the value of the "msg" field.
+func (bmu *BatchMsgUpdate) ClearMsg() *BatchMsgUpdate {
+	bmu.mutation.ClearMsg()
+	return bmu
+}
+
+// SetTag sets the "tag" field.
+func (bmu *BatchMsgUpdate) SetTag(s string) *BatchMsgUpdate {
+	bmu.mutation.SetTag(s)
+	return bmu
+}
+
+// SetNillableTag sets the "tag" field if the given value is not nil.
+func (bmu *BatchMsgUpdate) SetNillableTag(s *string) *BatchMsgUpdate {
+	if s != nil {
+		bmu.SetTag(*s)
+	}
+	return bmu
+}
+
+// ClearTag clears the value of the "tag" field.
+func (bmu *BatchMsgUpdate) ClearTag() *BatchMsgUpdate {
+	bmu.mutation.ClearTag()
+	return bmu
+}
+
+// SetTotal sets the "total" field.
+func (bmu *BatchMsgUpdate) SetTotal(i int32) *BatchMsgUpdate {
+	bmu.mutation.ResetTotal()
+	bmu.mutation.SetTotal(i)
+	return bmu
+}
+
+// SetNillableTotal sets the "total" field if the given value is not nil.
+func (bmu *BatchMsgUpdate) SetNillableTotal(i *int32) *BatchMsgUpdate {
+	if i != nil {
+		bmu.SetTotal(*i)
+	}
+	return bmu
+}
+
+// AddTotal adds i to the "total" field.
+func (bmu *BatchMsgUpdate) AddTotal(i int32) *BatchMsgUpdate {
+	bmu.mutation.AddTotal(i)
+	return bmu
+}
+
+// ClearTotal clears the value of the "total" field.
+func (bmu *BatchMsgUpdate) ClearTotal() *BatchMsgUpdate {
+	bmu.mutation.ClearTotal()
+	return bmu
+}
+
+// SetSuccess sets the "success" field.
+func (bmu *BatchMsgUpdate) SetSuccess(i int32) *BatchMsgUpdate {
+	bmu.mutation.ResetSuccess()
+	bmu.mutation.SetSuccess(i)
+	return bmu
+}
+
+// SetNillableSuccess sets the "success" field if the given value is not nil.
+func (bmu *BatchMsgUpdate) SetNillableSuccess(i *int32) *BatchMsgUpdate {
+	if i != nil {
+		bmu.SetSuccess(*i)
+	}
+	return bmu
+}
+
+// AddSuccess adds i to the "success" field.
+func (bmu *BatchMsgUpdate) AddSuccess(i int32) *BatchMsgUpdate {
+	bmu.mutation.AddSuccess(i)
+	return bmu
+}
+
+// ClearSuccess clears the value of the "success" field.
+func (bmu *BatchMsgUpdate) ClearSuccess() *BatchMsgUpdate {
+	bmu.mutation.ClearSuccess()
+	return bmu
+}
+
+// SetFail sets the "fail" field.
+func (bmu *BatchMsgUpdate) SetFail(i int32) *BatchMsgUpdate {
+	bmu.mutation.ResetFail()
+	bmu.mutation.SetFail(i)
+	return bmu
+}
+
+// SetNillableFail sets the "fail" field if the given value is not nil.
+func (bmu *BatchMsgUpdate) SetNillableFail(i *int32) *BatchMsgUpdate {
+	if i != nil {
+		bmu.SetFail(*i)
+	}
+	return bmu
+}
+
+// AddFail adds i to the "fail" field.
+func (bmu *BatchMsgUpdate) AddFail(i int32) *BatchMsgUpdate {
+	bmu.mutation.AddFail(i)
+	return bmu
+}
+
+// ClearFail clears the value of the "fail" field.
+func (bmu *BatchMsgUpdate) ClearFail() *BatchMsgUpdate {
+	bmu.mutation.ClearFail()
+	return bmu
+}
+
+// SetStartTime sets the "start_time" field.
+func (bmu *BatchMsgUpdate) SetStartTime(t time.Time) *BatchMsgUpdate {
+	bmu.mutation.SetStartTime(t)
+	return bmu
+}
+
+// SetNillableStartTime sets the "start_time" field if the given value is not nil.
+func (bmu *BatchMsgUpdate) SetNillableStartTime(t *time.Time) *BatchMsgUpdate {
+	if t != nil {
+		bmu.SetStartTime(*t)
+	}
+	return bmu
+}
+
+// ClearStartTime clears the value of the "start_time" field.
+func (bmu *BatchMsgUpdate) ClearStartTime() *BatchMsgUpdate {
+	bmu.mutation.ClearStartTime()
+	return bmu
+}
+
+// SetStopTime sets the "stop_time" field.
+func (bmu *BatchMsgUpdate) SetStopTime(t time.Time) *BatchMsgUpdate {
+	bmu.mutation.SetStopTime(t)
+	return bmu
+}
+
+// SetNillableStopTime sets the "stop_time" field if the given value is not nil.
+func (bmu *BatchMsgUpdate) SetNillableStopTime(t *time.Time) *BatchMsgUpdate {
+	if t != nil {
+		bmu.SetStopTime(*t)
+	}
+	return bmu
+}
+
+// ClearStopTime clears the value of the "stop_time" field.
+func (bmu *BatchMsgUpdate) ClearStopTime() *BatchMsgUpdate {
+	bmu.mutation.ClearStopTime()
+	return bmu
+}
+
+// Mutation returns the BatchMsgMutation object of the builder.
+func (bmu *BatchMsgUpdate) Mutation() *BatchMsgMutation {
+	return bmu.mutation
+}
+
+// Save executes the query and returns the number of nodes affected by the update operation.
+func (bmu *BatchMsgUpdate) Save(ctx context.Context) (int, error) {
+	if err := bmu.defaults(); err != nil {
+		return 0, err
+	}
+	return withHooks(ctx, bmu.sqlSave, bmu.mutation, bmu.hooks)
+}
+
+// SaveX is like Save, but panics if an error occurs.
+func (bmu *BatchMsgUpdate) SaveX(ctx context.Context) int {
+	affected, err := bmu.Save(ctx)
+	if err != nil {
+		panic(err)
+	}
+	return affected
+}
+
+// Exec executes the query.
+func (bmu *BatchMsgUpdate) Exec(ctx context.Context) error {
+	_, err := bmu.Save(ctx)
+	return err
+}
+
+// ExecX is like Exec, but panics if an error occurs.
+func (bmu *BatchMsgUpdate) ExecX(ctx context.Context) {
+	if err := bmu.Exec(ctx); err != nil {
+		panic(err)
+	}
+}
+
+// defaults sets the default values of the builder before save.
+func (bmu *BatchMsgUpdate) defaults() error {
+	if _, ok := bmu.mutation.UpdatedAt(); !ok {
+		if batchmsg.UpdateDefaultUpdatedAt == nil {
+			return fmt.Errorf("ent: uninitialized batchmsg.UpdateDefaultUpdatedAt (forgotten import ent/runtime?)")
+		}
+		v := batchmsg.UpdateDefaultUpdatedAt()
+		bmu.mutation.SetUpdatedAt(v)
+	}
+	return nil
+}
+
+func (bmu *BatchMsgUpdate) sqlSave(ctx context.Context) (n int, err error) {
+	_spec := sqlgraph.NewUpdateSpec(batchmsg.Table, batchmsg.Columns, sqlgraph.NewFieldSpec(batchmsg.FieldID, field.TypeUint64))
+	if ps := bmu.mutation.predicates; len(ps) > 0 {
+		_spec.Predicate = func(selector *sql.Selector) {
+			for i := range ps {
+				ps[i](selector)
+			}
+		}
+	}
+	if value, ok := bmu.mutation.UpdatedAt(); ok {
+		_spec.SetField(batchmsg.FieldUpdatedAt, field.TypeTime, value)
+	}
+	if value, ok := bmu.mutation.DeletedAt(); ok {
+		_spec.SetField(batchmsg.FieldDeletedAt, field.TypeTime, value)
+	}
+	if bmu.mutation.DeletedAtCleared() {
+		_spec.ClearField(batchmsg.FieldDeletedAt, field.TypeTime)
+	}
+	if value, ok := bmu.mutation.Status(); ok {
+		_spec.SetField(batchmsg.FieldStatus, field.TypeUint8, value)
+	}
+	if value, ok := bmu.mutation.AddedStatus(); ok {
+		_spec.AddField(batchmsg.FieldStatus, field.TypeUint8, value)
+	}
+	if bmu.mutation.StatusCleared() {
+		_spec.ClearField(batchmsg.FieldStatus, field.TypeUint8)
+	}
+	if value, ok := bmu.mutation.BatchNo(); ok {
+		_spec.SetField(batchmsg.FieldBatchNo, field.TypeString, value)
+	}
+	if bmu.mutation.BatchNoCleared() {
+		_spec.ClearField(batchmsg.FieldBatchNo, field.TypeString)
+	}
+	if value, ok := bmu.mutation.Fromwxid(); ok {
+		_spec.SetField(batchmsg.FieldFromwxid, field.TypeString, value)
+	}
+	if bmu.mutation.FromwxidCleared() {
+		_spec.ClearField(batchmsg.FieldFromwxid, field.TypeString)
+	}
+	if value, ok := bmu.mutation.Msg(); ok {
+		_spec.SetField(batchmsg.FieldMsg, field.TypeString, value)
+	}
+	if bmu.mutation.MsgCleared() {
+		_spec.ClearField(batchmsg.FieldMsg, field.TypeString)
+	}
+	if value, ok := bmu.mutation.Tag(); ok {
+		_spec.SetField(batchmsg.FieldTag, field.TypeString, value)
+	}
+	if bmu.mutation.TagCleared() {
+		_spec.ClearField(batchmsg.FieldTag, field.TypeString)
+	}
+	if value, ok := bmu.mutation.Total(); ok {
+		_spec.SetField(batchmsg.FieldTotal, field.TypeInt32, value)
+	}
+	if value, ok := bmu.mutation.AddedTotal(); ok {
+		_spec.AddField(batchmsg.FieldTotal, field.TypeInt32, value)
+	}
+	if bmu.mutation.TotalCleared() {
+		_spec.ClearField(batchmsg.FieldTotal, field.TypeInt32)
+	}
+	if value, ok := bmu.mutation.Success(); ok {
+		_spec.SetField(batchmsg.FieldSuccess, field.TypeInt32, value)
+	}
+	if value, ok := bmu.mutation.AddedSuccess(); ok {
+		_spec.AddField(batchmsg.FieldSuccess, field.TypeInt32, value)
+	}
+	if bmu.mutation.SuccessCleared() {
+		_spec.ClearField(batchmsg.FieldSuccess, field.TypeInt32)
+	}
+	if value, ok := bmu.mutation.Fail(); ok {
+		_spec.SetField(batchmsg.FieldFail, field.TypeInt32, value)
+	}
+	if value, ok := bmu.mutation.AddedFail(); ok {
+		_spec.AddField(batchmsg.FieldFail, field.TypeInt32, value)
+	}
+	if bmu.mutation.FailCleared() {
+		_spec.ClearField(batchmsg.FieldFail, field.TypeInt32)
+	}
+	if value, ok := bmu.mutation.StartTime(); ok {
+		_spec.SetField(batchmsg.FieldStartTime, field.TypeTime, value)
+	}
+	if bmu.mutation.StartTimeCleared() {
+		_spec.ClearField(batchmsg.FieldStartTime, field.TypeTime)
+	}
+	if value, ok := bmu.mutation.StopTime(); ok {
+		_spec.SetField(batchmsg.FieldStopTime, field.TypeTime, value)
+	}
+	if bmu.mutation.StopTimeCleared() {
+		_spec.ClearField(batchmsg.FieldStopTime, field.TypeTime)
+	}
+	if n, err = sqlgraph.UpdateNodes(ctx, bmu.driver, _spec); err != nil {
+		if _, ok := err.(*sqlgraph.NotFoundError); ok {
+			err = &NotFoundError{batchmsg.Label}
+		} else if sqlgraph.IsConstraintError(err) {
+			err = &ConstraintError{msg: err.Error(), wrap: err}
+		}
+		return 0, err
+	}
+	bmu.mutation.done = true
+	return n, nil
+}
+
+// BatchMsgUpdateOne is the builder for updating a single BatchMsg entity.
+type BatchMsgUpdateOne struct {
+	config
+	fields   []string
+	hooks    []Hook
+	mutation *BatchMsgMutation
+}
+
+// SetUpdatedAt sets the "updated_at" field.
+func (bmuo *BatchMsgUpdateOne) SetUpdatedAt(t time.Time) *BatchMsgUpdateOne {
+	bmuo.mutation.SetUpdatedAt(t)
+	return bmuo
+}
+
+// SetDeletedAt sets the "deleted_at" field.
+func (bmuo *BatchMsgUpdateOne) SetDeletedAt(t time.Time) *BatchMsgUpdateOne {
+	bmuo.mutation.SetDeletedAt(t)
+	return bmuo
+}
+
+// SetNillableDeletedAt sets the "deleted_at" field if the given value is not nil.
+func (bmuo *BatchMsgUpdateOne) SetNillableDeletedAt(t *time.Time) *BatchMsgUpdateOne {
+	if t != nil {
+		bmuo.SetDeletedAt(*t)
+	}
+	return bmuo
+}
+
+// ClearDeletedAt clears the value of the "deleted_at" field.
+func (bmuo *BatchMsgUpdateOne) ClearDeletedAt() *BatchMsgUpdateOne {
+	bmuo.mutation.ClearDeletedAt()
+	return bmuo
+}
+
+// SetStatus sets the "status" field.
+func (bmuo *BatchMsgUpdateOne) SetStatus(u uint8) *BatchMsgUpdateOne {
+	bmuo.mutation.ResetStatus()
+	bmuo.mutation.SetStatus(u)
+	return bmuo
+}
+
+// SetNillableStatus sets the "status" field if the given value is not nil.
+func (bmuo *BatchMsgUpdateOne) SetNillableStatus(u *uint8) *BatchMsgUpdateOne {
+	if u != nil {
+		bmuo.SetStatus(*u)
+	}
+	return bmuo
+}
+
+// AddStatus adds u to the "status" field.
+func (bmuo *BatchMsgUpdateOne) AddStatus(u int8) *BatchMsgUpdateOne {
+	bmuo.mutation.AddStatus(u)
+	return bmuo
+}
+
+// ClearStatus clears the value of the "status" field.
+func (bmuo *BatchMsgUpdateOne) ClearStatus() *BatchMsgUpdateOne {
+	bmuo.mutation.ClearStatus()
+	return bmuo
+}
+
+// SetBatchNo sets the "batch_no" field.
+func (bmuo *BatchMsgUpdateOne) SetBatchNo(s string) *BatchMsgUpdateOne {
+	bmuo.mutation.SetBatchNo(s)
+	return bmuo
+}
+
+// SetNillableBatchNo sets the "batch_no" field if the given value is not nil.
+func (bmuo *BatchMsgUpdateOne) SetNillableBatchNo(s *string) *BatchMsgUpdateOne {
+	if s != nil {
+		bmuo.SetBatchNo(*s)
+	}
+	return bmuo
+}
+
+// ClearBatchNo clears the value of the "batch_no" field.
+func (bmuo *BatchMsgUpdateOne) ClearBatchNo() *BatchMsgUpdateOne {
+	bmuo.mutation.ClearBatchNo()
+	return bmuo
+}
+
+// SetFromwxid sets the "fromwxid" field.
+func (bmuo *BatchMsgUpdateOne) SetFromwxid(s string) *BatchMsgUpdateOne {
+	bmuo.mutation.SetFromwxid(s)
+	return bmuo
+}
+
+// SetNillableFromwxid sets the "fromwxid" field if the given value is not nil.
+func (bmuo *BatchMsgUpdateOne) SetNillableFromwxid(s *string) *BatchMsgUpdateOne {
+	if s != nil {
+		bmuo.SetFromwxid(*s)
+	}
+	return bmuo
+}
+
+// ClearFromwxid clears the value of the "fromwxid" field.
+func (bmuo *BatchMsgUpdateOne) ClearFromwxid() *BatchMsgUpdateOne {
+	bmuo.mutation.ClearFromwxid()
+	return bmuo
+}
+
+// SetMsg sets the "msg" field.
+func (bmuo *BatchMsgUpdateOne) SetMsg(s string) *BatchMsgUpdateOne {
+	bmuo.mutation.SetMsg(s)
+	return bmuo
+}
+
+// SetNillableMsg sets the "msg" field if the given value is not nil.
+func (bmuo *BatchMsgUpdateOne) SetNillableMsg(s *string) *BatchMsgUpdateOne {
+	if s != nil {
+		bmuo.SetMsg(*s)
+	}
+	return bmuo
+}
+
+// ClearMsg clears the value of the "msg" field.
+func (bmuo *BatchMsgUpdateOne) ClearMsg() *BatchMsgUpdateOne {
+	bmuo.mutation.ClearMsg()
+	return bmuo
+}
+
+// SetTag sets the "tag" field.
+func (bmuo *BatchMsgUpdateOne) SetTag(s string) *BatchMsgUpdateOne {
+	bmuo.mutation.SetTag(s)
+	return bmuo
+}
+
+// SetNillableTag sets the "tag" field if the given value is not nil.
+func (bmuo *BatchMsgUpdateOne) SetNillableTag(s *string) *BatchMsgUpdateOne {
+	if s != nil {
+		bmuo.SetTag(*s)
+	}
+	return bmuo
+}
+
+// ClearTag clears the value of the "tag" field.
+func (bmuo *BatchMsgUpdateOne) ClearTag() *BatchMsgUpdateOne {
+	bmuo.mutation.ClearTag()
+	return bmuo
+}
+
+// SetTotal sets the "total" field.
+func (bmuo *BatchMsgUpdateOne) SetTotal(i int32) *BatchMsgUpdateOne {
+	bmuo.mutation.ResetTotal()
+	bmuo.mutation.SetTotal(i)
+	return bmuo
+}
+
+// SetNillableTotal sets the "total" field if the given value is not nil.
+func (bmuo *BatchMsgUpdateOne) SetNillableTotal(i *int32) *BatchMsgUpdateOne {
+	if i != nil {
+		bmuo.SetTotal(*i)
+	}
+	return bmuo
+}
+
+// AddTotal adds i to the "total" field.
+func (bmuo *BatchMsgUpdateOne) AddTotal(i int32) *BatchMsgUpdateOne {
+	bmuo.mutation.AddTotal(i)
+	return bmuo
+}
+
+// ClearTotal clears the value of the "total" field.
+func (bmuo *BatchMsgUpdateOne) ClearTotal() *BatchMsgUpdateOne {
+	bmuo.mutation.ClearTotal()
+	return bmuo
+}
+
+// SetSuccess sets the "success" field.
+func (bmuo *BatchMsgUpdateOne) SetSuccess(i int32) *BatchMsgUpdateOne {
+	bmuo.mutation.ResetSuccess()
+	bmuo.mutation.SetSuccess(i)
+	return bmuo
+}
+
+// SetNillableSuccess sets the "success" field if the given value is not nil.
+func (bmuo *BatchMsgUpdateOne) SetNillableSuccess(i *int32) *BatchMsgUpdateOne {
+	if i != nil {
+		bmuo.SetSuccess(*i)
+	}
+	return bmuo
+}
+
+// AddSuccess adds i to the "success" field.
+func (bmuo *BatchMsgUpdateOne) AddSuccess(i int32) *BatchMsgUpdateOne {
+	bmuo.mutation.AddSuccess(i)
+	return bmuo
+}
+
+// ClearSuccess clears the value of the "success" field.
+func (bmuo *BatchMsgUpdateOne) ClearSuccess() *BatchMsgUpdateOne {
+	bmuo.mutation.ClearSuccess()
+	return bmuo
+}
+
+// SetFail sets the "fail" field.
+func (bmuo *BatchMsgUpdateOne) SetFail(i int32) *BatchMsgUpdateOne {
+	bmuo.mutation.ResetFail()
+	bmuo.mutation.SetFail(i)
+	return bmuo
+}
+
+// SetNillableFail sets the "fail" field if the given value is not nil.
+func (bmuo *BatchMsgUpdateOne) SetNillableFail(i *int32) *BatchMsgUpdateOne {
+	if i != nil {
+		bmuo.SetFail(*i)
+	}
+	return bmuo
+}
+
+// AddFail adds i to the "fail" field.
+func (bmuo *BatchMsgUpdateOne) AddFail(i int32) *BatchMsgUpdateOne {
+	bmuo.mutation.AddFail(i)
+	return bmuo
+}
+
+// ClearFail clears the value of the "fail" field.
+func (bmuo *BatchMsgUpdateOne) ClearFail() *BatchMsgUpdateOne {
+	bmuo.mutation.ClearFail()
+	return bmuo
+}
+
+// SetStartTime sets the "start_time" field.
+func (bmuo *BatchMsgUpdateOne) SetStartTime(t time.Time) *BatchMsgUpdateOne {
+	bmuo.mutation.SetStartTime(t)
+	return bmuo
+}
+
+// SetNillableStartTime sets the "start_time" field if the given value is not nil.
+func (bmuo *BatchMsgUpdateOne) SetNillableStartTime(t *time.Time) *BatchMsgUpdateOne {
+	if t != nil {
+		bmuo.SetStartTime(*t)
+	}
+	return bmuo
+}
+
+// ClearStartTime clears the value of the "start_time" field.
+func (bmuo *BatchMsgUpdateOne) ClearStartTime() *BatchMsgUpdateOne {
+	bmuo.mutation.ClearStartTime()
+	return bmuo
+}
+
+// SetStopTime sets the "stop_time" field.
+func (bmuo *BatchMsgUpdateOne) SetStopTime(t time.Time) *BatchMsgUpdateOne {
+	bmuo.mutation.SetStopTime(t)
+	return bmuo
+}
+
+// SetNillableStopTime sets the "stop_time" field if the given value is not nil.
+func (bmuo *BatchMsgUpdateOne) SetNillableStopTime(t *time.Time) *BatchMsgUpdateOne {
+	if t != nil {
+		bmuo.SetStopTime(*t)
+	}
+	return bmuo
+}
+
+// ClearStopTime clears the value of the "stop_time" field.
+func (bmuo *BatchMsgUpdateOne) ClearStopTime() *BatchMsgUpdateOne {
+	bmuo.mutation.ClearStopTime()
+	return bmuo
+}
+
+// Mutation returns the BatchMsgMutation object of the builder.
+func (bmuo *BatchMsgUpdateOne) Mutation() *BatchMsgMutation {
+	return bmuo.mutation
+}
+
+// Where appends a list predicates to the BatchMsgUpdate builder.
+func (bmuo *BatchMsgUpdateOne) Where(ps ...predicate.BatchMsg) *BatchMsgUpdateOne {
+	bmuo.mutation.Where(ps...)
+	return bmuo
+}
+
+// Select allows selecting one or more fields (columns) of the returned entity.
+// The default is selecting all fields defined in the entity schema.
+func (bmuo *BatchMsgUpdateOne) Select(field string, fields ...string) *BatchMsgUpdateOne {
+	bmuo.fields = append([]string{field}, fields...)
+	return bmuo
+}
+
+// Save executes the query and returns the updated BatchMsg entity.
+func (bmuo *BatchMsgUpdateOne) Save(ctx context.Context) (*BatchMsg, error) {
+	if err := bmuo.defaults(); err != nil {
+		return nil, err
+	}
+	return withHooks(ctx, bmuo.sqlSave, bmuo.mutation, bmuo.hooks)
+}
+
+// SaveX is like Save, but panics if an error occurs.
+func (bmuo *BatchMsgUpdateOne) SaveX(ctx context.Context) *BatchMsg {
+	node, err := bmuo.Save(ctx)
+	if err != nil {
+		panic(err)
+	}
+	return node
+}
+
+// Exec executes the query on the entity.
+func (bmuo *BatchMsgUpdateOne) Exec(ctx context.Context) error {
+	_, err := bmuo.Save(ctx)
+	return err
+}
+
+// ExecX is like Exec, but panics if an error occurs.
+func (bmuo *BatchMsgUpdateOne) ExecX(ctx context.Context) {
+	if err := bmuo.Exec(ctx); err != nil {
+		panic(err)
+	}
+}
+
+// defaults sets the default values of the builder before save.
+func (bmuo *BatchMsgUpdateOne) defaults() error {
+	if _, ok := bmuo.mutation.UpdatedAt(); !ok {
+		if batchmsg.UpdateDefaultUpdatedAt == nil {
+			return fmt.Errorf("ent: uninitialized batchmsg.UpdateDefaultUpdatedAt (forgotten import ent/runtime?)")
+		}
+		v := batchmsg.UpdateDefaultUpdatedAt()
+		bmuo.mutation.SetUpdatedAt(v)
+	}
+	return nil
+}
+
+func (bmuo *BatchMsgUpdateOne) sqlSave(ctx context.Context) (_node *BatchMsg, err error) {
+	_spec := sqlgraph.NewUpdateSpec(batchmsg.Table, batchmsg.Columns, sqlgraph.NewFieldSpec(batchmsg.FieldID, field.TypeUint64))
+	id, ok := bmuo.mutation.ID()
+	if !ok {
+		return nil, &ValidationError{Name: "id", err: errors.New(`ent: missing "BatchMsg.id" for update`)}
+	}
+	_spec.Node.ID.Value = id
+	if fields := bmuo.fields; len(fields) > 0 {
+		_spec.Node.Columns = make([]string, 0, len(fields))
+		_spec.Node.Columns = append(_spec.Node.Columns, batchmsg.FieldID)
+		for _, f := range fields {
+			if !batchmsg.ValidColumn(f) {
+				return nil, &ValidationError{Name: f, err: fmt.Errorf("ent: invalid field %q for query", f)}
+			}
+			if f != batchmsg.FieldID {
+				_spec.Node.Columns = append(_spec.Node.Columns, f)
+			}
+		}
+	}
+	if ps := bmuo.mutation.predicates; len(ps) > 0 {
+		_spec.Predicate = func(selector *sql.Selector) {
+			for i := range ps {
+				ps[i](selector)
+			}
+		}
+	}
+	if value, ok := bmuo.mutation.UpdatedAt(); ok {
+		_spec.SetField(batchmsg.FieldUpdatedAt, field.TypeTime, value)
+	}
+	if value, ok := bmuo.mutation.DeletedAt(); ok {
+		_spec.SetField(batchmsg.FieldDeletedAt, field.TypeTime, value)
+	}
+	if bmuo.mutation.DeletedAtCleared() {
+		_spec.ClearField(batchmsg.FieldDeletedAt, field.TypeTime)
+	}
+	if value, ok := bmuo.mutation.Status(); ok {
+		_spec.SetField(batchmsg.FieldStatus, field.TypeUint8, value)
+	}
+	if value, ok := bmuo.mutation.AddedStatus(); ok {
+		_spec.AddField(batchmsg.FieldStatus, field.TypeUint8, value)
+	}
+	if bmuo.mutation.StatusCleared() {
+		_spec.ClearField(batchmsg.FieldStatus, field.TypeUint8)
+	}
+	if value, ok := bmuo.mutation.BatchNo(); ok {
+		_spec.SetField(batchmsg.FieldBatchNo, field.TypeString, value)
+	}
+	if bmuo.mutation.BatchNoCleared() {
+		_spec.ClearField(batchmsg.FieldBatchNo, field.TypeString)
+	}
+	if value, ok := bmuo.mutation.Fromwxid(); ok {
+		_spec.SetField(batchmsg.FieldFromwxid, field.TypeString, value)
+	}
+	if bmuo.mutation.FromwxidCleared() {
+		_spec.ClearField(batchmsg.FieldFromwxid, field.TypeString)
+	}
+	if value, ok := bmuo.mutation.Msg(); ok {
+		_spec.SetField(batchmsg.FieldMsg, field.TypeString, value)
+	}
+	if bmuo.mutation.MsgCleared() {
+		_spec.ClearField(batchmsg.FieldMsg, field.TypeString)
+	}
+	if value, ok := bmuo.mutation.Tag(); ok {
+		_spec.SetField(batchmsg.FieldTag, field.TypeString, value)
+	}
+	if bmuo.mutation.TagCleared() {
+		_spec.ClearField(batchmsg.FieldTag, field.TypeString)
+	}
+	if value, ok := bmuo.mutation.Total(); ok {
+		_spec.SetField(batchmsg.FieldTotal, field.TypeInt32, value)
+	}
+	if value, ok := bmuo.mutation.AddedTotal(); ok {
+		_spec.AddField(batchmsg.FieldTotal, field.TypeInt32, value)
+	}
+	if bmuo.mutation.TotalCleared() {
+		_spec.ClearField(batchmsg.FieldTotal, field.TypeInt32)
+	}
+	if value, ok := bmuo.mutation.Success(); ok {
+		_spec.SetField(batchmsg.FieldSuccess, field.TypeInt32, value)
+	}
+	if value, ok := bmuo.mutation.AddedSuccess(); ok {
+		_spec.AddField(batchmsg.FieldSuccess, field.TypeInt32, value)
+	}
+	if bmuo.mutation.SuccessCleared() {
+		_spec.ClearField(batchmsg.FieldSuccess, field.TypeInt32)
+	}
+	if value, ok := bmuo.mutation.Fail(); ok {
+		_spec.SetField(batchmsg.FieldFail, field.TypeInt32, value)
+	}
+	if value, ok := bmuo.mutation.AddedFail(); ok {
+		_spec.AddField(batchmsg.FieldFail, field.TypeInt32, value)
+	}
+	if bmuo.mutation.FailCleared() {
+		_spec.ClearField(batchmsg.FieldFail, field.TypeInt32)
+	}
+	if value, ok := bmuo.mutation.StartTime(); ok {
+		_spec.SetField(batchmsg.FieldStartTime, field.TypeTime, value)
+	}
+	if bmuo.mutation.StartTimeCleared() {
+		_spec.ClearField(batchmsg.FieldStartTime, field.TypeTime)
+	}
+	if value, ok := bmuo.mutation.StopTime(); ok {
+		_spec.SetField(batchmsg.FieldStopTime, field.TypeTime, value)
+	}
+	if bmuo.mutation.StopTimeCleared() {
+		_spec.ClearField(batchmsg.FieldStopTime, field.TypeTime)
+	}
+	_node = &BatchMsg{config: bmuo.config}
+	_spec.Assign = _node.assignValues
+	_spec.ScanValues = _node.scanValues
+	if err = sqlgraph.UpdateNode(ctx, bmuo.driver, _spec); err != nil {
+		if _, ok := err.(*sqlgraph.NotFoundError); ok {
+			err = &NotFoundError{batchmsg.Label}
+		} else if sqlgraph.IsConstraintError(err) {
+			err = &ConstraintError{msg: err.Error(), wrap: err}
+		}
+		return nil, err
+	}
+	bmuo.mutation.done = true
+	return _node, nil
+}

+ 152 - 9
ent/client.go

@@ -11,6 +11,7 @@ import (
 
 	"wechat-api/ent/migrate"
 
+	"wechat-api/ent/batchmsg"
 	"wechat-api/ent/contact"
 	"wechat-api/ent/label"
 	"wechat-api/ent/labelrelationship"
@@ -35,6 +36,8 @@ type Client struct {
 	config
 	// Schema is the client for creating, migrating and dropping schema.
 	Schema *migrate.Schema
+	// BatchMsg is the client for interacting with the BatchMsg builders.
+	BatchMsg *BatchMsgClient
 	// Contact is the client for interacting with the Contact builders.
 	Contact *ContactClient
 	// Label is the client for interacting with the Label builders.
@@ -66,6 +69,7 @@ func NewClient(opts ...Option) *Client {
 
 func (c *Client) init() {
 	c.Schema = migrate.NewSchema(c.driver)
+	c.BatchMsg = NewBatchMsgClient(c.config)
 	c.Contact = NewContactClient(c.config)
 	c.Label = NewLabelClient(c.config)
 	c.LabelRelationship = NewLabelRelationshipClient(c.config)
@@ -168,6 +172,7 @@ func (c *Client) Tx(ctx context.Context) (*Tx, error) {
 	return &Tx{
 		ctx:               ctx,
 		config:            cfg,
+		BatchMsg:          NewBatchMsgClient(cfg),
 		Contact:           NewContactClient(cfg),
 		Label:             NewLabelClient(cfg),
 		LabelRelationship: NewLabelRelationshipClient(cfg),
@@ -197,6 +202,7 @@ func (c *Client) BeginTx(ctx context.Context, opts *sql.TxOptions) (*Tx, error)
 	return &Tx{
 		ctx:               ctx,
 		config:            cfg,
+		BatchMsg:          NewBatchMsgClient(cfg),
 		Contact:           NewContactClient(cfg),
 		Label:             NewLabelClient(cfg),
 		LabelRelationship: NewLabelRelationshipClient(cfg),
@@ -213,7 +219,7 @@ func (c *Client) BeginTx(ctx context.Context, opts *sql.TxOptions) (*Tx, error)
 // Debug returns a new debug-client. It's used to get verbose logging on specific operations.
 //
 //	client.Debug().
-//		Contact.
+//		BatchMsg.
 //		Query().
 //		Count(ctx)
 func (c *Client) Debug() *Client {
@@ -236,8 +242,8 @@ func (c *Client) Close() error {
 // In order to add hooks to a specific client, call: `client.Node.Use(...)`.
 func (c *Client) Use(hooks ...Hook) {
 	for _, n := range []interface{ Use(...Hook) }{
-		c.Contact, c.Label, c.LabelRelationship, c.Message, c.MessageRecords, c.Server,
-		c.SopNode, c.SopStage, c.SopTask, c.Wx,
+		c.BatchMsg, c.Contact, c.Label, c.LabelRelationship, c.Message,
+		c.MessageRecords, c.Server, c.SopNode, c.SopStage, c.SopTask, c.Wx,
 	} {
 		n.Use(hooks...)
 	}
@@ -247,8 +253,8 @@ func (c *Client) Use(hooks ...Hook) {
 // In order to add interceptors to a specific client, call: `client.Node.Intercept(...)`.
 func (c *Client) Intercept(interceptors ...Interceptor) {
 	for _, n := range []interface{ Intercept(...Interceptor) }{
-		c.Contact, c.Label, c.LabelRelationship, c.Message, c.MessageRecords, c.Server,
-		c.SopNode, c.SopStage, c.SopTask, c.Wx,
+		c.BatchMsg, c.Contact, c.Label, c.LabelRelationship, c.Message,
+		c.MessageRecords, c.Server, c.SopNode, c.SopStage, c.SopTask, c.Wx,
 	} {
 		n.Intercept(interceptors...)
 	}
@@ -257,6 +263,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 *BatchMsgMutation:
+		return c.BatchMsg.mutate(ctx, m)
 	case *ContactMutation:
 		return c.Contact.mutate(ctx, m)
 	case *LabelMutation:
@@ -282,6 +290,141 @@ func (c *Client) Mutate(ctx context.Context, m Mutation) (Value, error) {
 	}
 }
 
+// BatchMsgClient is a client for the BatchMsg schema.
+type BatchMsgClient struct {
+	config
+}
+
+// NewBatchMsgClient returns a client for the BatchMsg from the given config.
+func NewBatchMsgClient(c config) *BatchMsgClient {
+	return &BatchMsgClient{config: c}
+}
+
+// Use adds a list of mutation hooks to the hooks stack.
+// A call to `Use(f, g, h)` equals to `batchmsg.Hooks(f(g(h())))`.
+func (c *BatchMsgClient) Use(hooks ...Hook) {
+	c.hooks.BatchMsg = append(c.hooks.BatchMsg, hooks...)
+}
+
+// Intercept adds a list of query interceptors to the interceptors stack.
+// A call to `Intercept(f, g, h)` equals to `batchmsg.Intercept(f(g(h())))`.
+func (c *BatchMsgClient) Intercept(interceptors ...Interceptor) {
+	c.inters.BatchMsg = append(c.inters.BatchMsg, interceptors...)
+}
+
+// Create returns a builder for creating a BatchMsg entity.
+func (c *BatchMsgClient) Create() *BatchMsgCreate {
+	mutation := newBatchMsgMutation(c.config, OpCreate)
+	return &BatchMsgCreate{config: c.config, hooks: c.Hooks(), mutation: mutation}
+}
+
+// CreateBulk returns a builder for creating a bulk of BatchMsg entities.
+func (c *BatchMsgClient) CreateBulk(builders ...*BatchMsgCreate) *BatchMsgCreateBulk {
+	return &BatchMsgCreateBulk{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 *BatchMsgClient) MapCreateBulk(slice any, setFunc func(*BatchMsgCreate, int)) *BatchMsgCreateBulk {
+	rv := reflect.ValueOf(slice)
+	if rv.Kind() != reflect.Slice {
+		return &BatchMsgCreateBulk{err: fmt.Errorf("calling to BatchMsgClient.MapCreateBulk with wrong type %T, need slice", slice)}
+	}
+	builders := make([]*BatchMsgCreate, rv.Len())
+	for i := 0; i < rv.Len(); i++ {
+		builders[i] = c.Create()
+		setFunc(builders[i], i)
+	}
+	return &BatchMsgCreateBulk{config: c.config, builders: builders}
+}
+
+// Update returns an update builder for BatchMsg.
+func (c *BatchMsgClient) Update() *BatchMsgUpdate {
+	mutation := newBatchMsgMutation(c.config, OpUpdate)
+	return &BatchMsgUpdate{config: c.config, hooks: c.Hooks(), mutation: mutation}
+}
+
+// UpdateOne returns an update builder for the given entity.
+func (c *BatchMsgClient) UpdateOne(bm *BatchMsg) *BatchMsgUpdateOne {
+	mutation := newBatchMsgMutation(c.config, OpUpdateOne, withBatchMsg(bm))
+	return &BatchMsgUpdateOne{config: c.config, hooks: c.Hooks(), mutation: mutation}
+}
+
+// UpdateOneID returns an update builder for the given id.
+func (c *BatchMsgClient) UpdateOneID(id uint64) *BatchMsgUpdateOne {
+	mutation := newBatchMsgMutation(c.config, OpUpdateOne, withBatchMsgID(id))
+	return &BatchMsgUpdateOne{config: c.config, hooks: c.Hooks(), mutation: mutation}
+}
+
+// Delete returns a delete builder for BatchMsg.
+func (c *BatchMsgClient) Delete() *BatchMsgDelete {
+	mutation := newBatchMsgMutation(c.config, OpDelete)
+	return &BatchMsgDelete{config: c.config, hooks: c.Hooks(), mutation: mutation}
+}
+
+// DeleteOne returns a builder for deleting the given entity.
+func (c *BatchMsgClient) DeleteOne(bm *BatchMsg) *BatchMsgDeleteOne {
+	return c.DeleteOneID(bm.ID)
+}
+
+// DeleteOneID returns a builder for deleting the given entity by its id.
+func (c *BatchMsgClient) DeleteOneID(id uint64) *BatchMsgDeleteOne {
+	builder := c.Delete().Where(batchmsg.ID(id))
+	builder.mutation.id = &id
+	builder.mutation.op = OpDeleteOne
+	return &BatchMsgDeleteOne{builder}
+}
+
+// Query returns a query builder for BatchMsg.
+func (c *BatchMsgClient) Query() *BatchMsgQuery {
+	return &BatchMsgQuery{
+		config: c.config,
+		ctx:    &QueryContext{Type: TypeBatchMsg},
+		inters: c.Interceptors(),
+	}
+}
+
+// Get returns a BatchMsg entity by its id.
+func (c *BatchMsgClient) Get(ctx context.Context, id uint64) (*BatchMsg, error) {
+	return c.Query().Where(batchmsg.ID(id)).Only(ctx)
+}
+
+// GetX is like Get, but panics if an error occurs.
+func (c *BatchMsgClient) GetX(ctx context.Context, id uint64) *BatchMsg {
+	obj, err := c.Get(ctx, id)
+	if err != nil {
+		panic(err)
+	}
+	return obj
+}
+
+// Hooks returns the client hooks.
+func (c *BatchMsgClient) Hooks() []Hook {
+	hooks := c.hooks.BatchMsg
+	return append(hooks[:len(hooks):len(hooks)], batchmsg.Hooks[:]...)
+}
+
+// Interceptors returns the client interceptors.
+func (c *BatchMsgClient) Interceptors() []Interceptor {
+	inters := c.inters.BatchMsg
+	return append(inters[:len(inters):len(inters)], batchmsg.Interceptors[:]...)
+}
+
+func (c *BatchMsgClient) mutate(ctx context.Context, m *BatchMsgMutation) (Value, error) {
+	switch m.Op() {
+	case OpCreate:
+		return (&BatchMsgCreate{config: c.config, hooks: c.Hooks(), mutation: m}).Save(ctx)
+	case OpUpdate:
+		return (&BatchMsgUpdate{config: c.config, hooks: c.Hooks(), mutation: m}).Save(ctx)
+	case OpUpdateOne:
+		return (&BatchMsgUpdateOne{config: c.config, hooks: c.Hooks(), mutation: m}).Save(ctx)
+	case OpDelete, OpDeleteOne:
+		return (&BatchMsgDelete{config: c.config, hooks: c.Hooks(), mutation: m}).Exec(ctx)
+	default:
+		return nil, fmt.Errorf("ent: unknown BatchMsg mutation op: %q", m.Op())
+	}
+}
+
 // ContactClient is a client for the Contact schema.
 type ContactClient struct {
 	config
@@ -1889,12 +2032,12 @@ func (c *WxClient) mutate(ctx context.Context, m *WxMutation) (Value, error) {
 // hooks and interceptors per client, for fast access.
 type (
 	hooks struct {
-		Contact, Label, LabelRelationship, Message, MessageRecords, Server, SopNode,
-		SopStage, SopTask, Wx []ent.Hook
+		BatchMsg, Contact, Label, LabelRelationship, Message, MessageRecords, Server,
+		SopNode, SopStage, SopTask, Wx []ent.Hook
 	}
 	inters struct {
-		Contact, Label, LabelRelationship, Message, MessageRecords, Server, SopNode,
-		SopStage, SopTask, Wx []ent.Interceptor
+		BatchMsg, Contact, Label, LabelRelationship, Message, MessageRecords, Server,
+		SopNode, SopStage, SopTask, Wx []ent.Interceptor
 	}
 )
 

+ 5 - 5
ent/contact/contact.go

@@ -58,19 +58,19 @@ const (
 	// EdgeContactMessages holds the string denoting the contact_messages edge name in mutations.
 	EdgeContactMessages = "contact_messages"
 	// Table holds the table name of the contact in the database.
-	Table = "contact"
+	Table = "contacts"
 	// ContactRelationshipsTable is the table that holds the contact_relationships relation/edge.
-	ContactRelationshipsTable = "label_relationship"
+	ContactRelationshipsTable = "label_relationships"
 	// ContactRelationshipsInverseTable is the table name for the LabelRelationship entity.
 	// It exists in this package in order to avoid circular dependency with the "labelrelationship" package.
-	ContactRelationshipsInverseTable = "label_relationship"
+	ContactRelationshipsInverseTable = "label_relationships"
 	// ContactRelationshipsColumn is the table column denoting the contact_relationships relation/edge.
 	ContactRelationshipsColumn = "contact_id"
 	// ContactMessagesTable is the table that holds the contact_messages relation/edge.
-	ContactMessagesTable = "message_records"
+	ContactMessagesTable = "message_recordss"
 	// ContactMessagesInverseTable is the table name for the MessageRecords entity.
 	// It exists in this package in order to avoid circular dependency with the "messagerecords" package.
-	ContactMessagesInverseTable = "message_records"
+	ContactMessagesInverseTable = "message_recordss"
 	// ContactMessagesColumn is the table column denoting the contact_messages relation/edge.
 	ContactMessagesColumn = "contact_id"
 )

+ 2 - 0
ent/ent.go

@@ -8,6 +8,7 @@ import (
 	"fmt"
 	"reflect"
 	"sync"
+	"wechat-api/ent/batchmsg"
 	"wechat-api/ent/contact"
 	"wechat-api/ent/label"
 	"wechat-api/ent/labelrelationship"
@@ -82,6 +83,7 @@ var (
 func checkColumn(table, column string) error {
 	initCheck.Do(func() {
 		columnCheck = sql.NewColumnCheck(map[string]func(string) bool{
+			batchmsg.Table:          batchmsg.ValidColumn,
 			contact.Table:           contact.ValidColumn,
 			label.Table:             label.ValidColumn,
 			labelrelationship.Table: labelrelationship.ValidColumn,

+ 12 - 0
ent/hook/hook.go

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

+ 30 - 0
ent/intercept/intercept.go

@@ -6,6 +6,7 @@ import (
 	"context"
 	"fmt"
 	"wechat-api/ent"
+	"wechat-api/ent/batchmsg"
 	"wechat-api/ent/contact"
 	"wechat-api/ent/label"
 	"wechat-api/ent/labelrelationship"
@@ -77,6 +78,33 @@ func (f TraverseFunc) Traverse(ctx context.Context, q ent.Query) error {
 	return f(ctx, query)
 }
 
+// The BatchMsgFunc type is an adapter to allow the use of ordinary function as a Querier.
+type BatchMsgFunc func(context.Context, *ent.BatchMsgQuery) (ent.Value, error)
+
+// Query calls f(ctx, q).
+func (f BatchMsgFunc) Query(ctx context.Context, q ent.Query) (ent.Value, error) {
+	if q, ok := q.(*ent.BatchMsgQuery); ok {
+		return f(ctx, q)
+	}
+	return nil, fmt.Errorf("unexpected query type %T. expect *ent.BatchMsgQuery", q)
+}
+
+// The TraverseBatchMsg type is an adapter to allow the use of ordinary function as Traverser.
+type TraverseBatchMsg func(context.Context, *ent.BatchMsgQuery) error
+
+// Intercept is a dummy implementation of Intercept that returns the next Querier in the pipeline.
+func (f TraverseBatchMsg) Intercept(next ent.Querier) ent.Querier {
+	return next
+}
+
+// Traverse calls f(ctx, q).
+func (f TraverseBatchMsg) Traverse(ctx context.Context, q ent.Query) error {
+	if q, ok := q.(*ent.BatchMsgQuery); ok {
+		return f(ctx, q)
+	}
+	return fmt.Errorf("unexpected query type %T. expect *ent.BatchMsgQuery", q)
+}
+
 // The ContactFunc type is an adapter to allow the use of ordinary function as a Querier.
 type ContactFunc func(context.Context, *ent.ContactQuery) (ent.Value, error)
 
@@ -350,6 +378,8 @@ func (f TraverseWx) Traverse(ctx context.Context, q ent.Query) error {
 // NewQuery returns the generic Query interface for the given typed query.
 func NewQuery(q ent.Query) (Query, error) {
 	switch q := q.(type) {
+	case *ent.BatchMsgQuery:
+		return &query[*ent.BatchMsgQuery, predicate.BatchMsg, batchmsg.OrderOption]{typ: ent.TypeBatchMsg, tq: q}, nil
 	case *ent.ContactQuery:
 		return &query[*ent.ContactQuery, predicate.Contact, contact.OrderOption]{typ: ent.TypeContact, tq: q}, nil
 	case *ent.LabelQuery:

+ 3 - 3
ent/label/label.go

@@ -36,12 +36,12 @@ const (
 	// EdgeLabelRelationships holds the string denoting the label_relationships edge name in mutations.
 	EdgeLabelRelationships = "label_relationships"
 	// Table holds the table name of the label in the database.
-	Table = "label"
+	Table = "labels"
 	// LabelRelationshipsTable is the table that holds the label_relationships relation/edge.
-	LabelRelationshipsTable = "label_relationship"
+	LabelRelationshipsTable = "label_relationships"
 	// LabelRelationshipsInverseTable is the table name for the LabelRelationship entity.
 	// It exists in this package in order to avoid circular dependency with the "labelrelationship" package.
-	LabelRelationshipsInverseTable = "label_relationship"
+	LabelRelationshipsInverseTable = "label_relationships"
 	// LabelRelationshipsColumn is the table column denoting the label_relationships relation/edge.
 	LabelRelationshipsColumn = "label_id"
 )

+ 5 - 5
ent/labelrelationship/labelrelationship.go

@@ -32,19 +32,19 @@ const (
 	// EdgeLabels holds the string denoting the labels edge name in mutations.
 	EdgeLabels = "labels"
 	// Table holds the table name of the labelrelationship in the database.
-	Table = "label_relationship"
+	Table = "label_relationships"
 	// ContactsTable is the table that holds the contacts relation/edge.
-	ContactsTable = "label_relationship"
+	ContactsTable = "label_relationships"
 	// ContactsInverseTable is the table name for the Contact entity.
 	// It exists in this package in order to avoid circular dependency with the "contact" package.
-	ContactsInverseTable = "contact"
+	ContactsInverseTable = "contacts"
 	// ContactsColumn is the table column denoting the contacts relation/edge.
 	ContactsColumn = "contact_id"
 	// LabelsTable is the table that holds the labels relation/edge.
-	LabelsTable = "label_relationship"
+	LabelsTable = "label_relationships"
 	// LabelsInverseTable is the table name for the Label entity.
 	// It exists in this package in order to avoid circular dependency with the "label" package.
-	LabelsInverseTable = "label"
+	LabelsInverseTable = "labels"
 	// LabelsColumn is the table column denoting the labels relation/edge.
 	LabelsColumn = "label_id"
 )

+ 1 - 1
ent/message/message.go

@@ -18,7 +18,7 @@ const (
 	// FieldContent holds the string denoting the content field in the database.
 	FieldContent = "content"
 	// Table holds the table name of the message in the database.
-	Table = "message"
+	Table = "messages"
 )
 
 // Columns holds all SQL columns for message fields.

+ 7 - 7
ent/messagerecords/messagerecords.go

@@ -54,26 +54,26 @@ const (
 	// EdgeMessageContact holds the string denoting the message_contact edge name in mutations.
 	EdgeMessageContact = "message_contact"
 	// Table holds the table name of the messagerecords in the database.
-	Table = "message_records"
+	Table = "message_recordss"
 	// SopStageTable is the table that holds the sop_stage relation/edge.
-	SopStageTable = "message_records"
+	SopStageTable = "message_recordss"
 	// SopStageInverseTable is the table name for the SopStage entity.
 	// It exists in this package in order to avoid circular dependency with the "sopstage" package.
-	SopStageInverseTable = "sop_stage"
+	SopStageInverseTable = "sop_stages"
 	// SopStageColumn is the table column denoting the sop_stage relation/edge.
 	SopStageColumn = "source_id"
 	// SopNodeTable is the table that holds the sop_node relation/edge.
-	SopNodeTable = "message_records"
+	SopNodeTable = "message_recordss"
 	// SopNodeInverseTable is the table name for the SopNode entity.
 	// It exists in this package in order to avoid circular dependency with the "sopnode" package.
-	SopNodeInverseTable = "sop_node"
+	SopNodeInverseTable = "sop_nodes"
 	// SopNodeColumn is the table column denoting the sop_node relation/edge.
 	SopNodeColumn = "sub_source_id"
 	// MessageContactTable is the table that holds the message_contact relation/edge.
-	MessageContactTable = "message_records"
+	MessageContactTable = "message_recordss"
 	// MessageContactInverseTable is the table name for the Contact entity.
 	// It exists in this package in order to avoid circular dependency with the "contact" package.
-	MessageContactInverseTable = "contact"
+	MessageContactInverseTable = "contacts"
 	// MessageContactColumn is the table column denoting the message_contact relation/edge.
 	MessageContactColumn = "contact_id"
 )

+ 185 - 151
ent/migrate/schema.go

@@ -9,8 +9,38 @@ import (
 )
 
 var (
-	// ContactColumns holds the columns for the "contact" table.
-	ContactColumns = []*schema.Column{
+	// BatchMsgsColumns holds the columns for the "batch_msgs" table.
+	BatchMsgsColumns = []*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: "deleted_at", Type: field.TypeTime, Nullable: true, Comment: "Delete Time | 删除日期"},
+		{Name: "status", Type: field.TypeUint8, Nullable: true, Comment: "状态 0 未开始 1 开始发送 2 发送完成 3 发送中止"},
+		{Name: "batch_no", Type: field.TypeString, Unique: true, Nullable: true, Comment: "批次号"},
+		{Name: "fromwxid", Type: field.TypeString, Nullable: true, Comment: "发送方微信ID"},
+		{Name: "msg", Type: field.TypeString, Nullable: true, Comment: "内容"},
+		{Name: "tag", Type: field.TypeString, Nullable: true, Comment: "发送规则 all 全部 tag1,tag2 按tag发送"},
+		{Name: "total", Type: field.TypeInt32, Nullable: true, Comment: "总数"},
+		{Name: "success", Type: field.TypeInt32, Nullable: true, Comment: "成功数量"},
+		{Name: "fail", Type: field.TypeInt32, Nullable: true, Comment: "失败数量"},
+		{Name: "start_time", Type: field.TypeTime, Nullable: true, Comment: "开始时间"},
+		{Name: "stop_time", Type: field.TypeTime, Nullable: true, Comment: "结束时间"},
+	}
+	// BatchMsgsTable holds the schema information for the "batch_msgs" table.
+	BatchMsgsTable = &schema.Table{
+		Name:       "batch_msgs",
+		Columns:    BatchMsgsColumns,
+		PrimaryKey: []*schema.Column{BatchMsgsColumns[0]},
+		Indexes: []*schema.Index{
+			{
+				Name:    "batchmsg_batch_no",
+				Unique:  true,
+				Columns: []*schema.Column{BatchMsgsColumns[5]},
+			},
+		},
+	}
+	// ContactsColumns holds the columns for the "contacts" table.
+	ContactsColumns = []*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 | 修改日期"},
@@ -32,36 +62,36 @@ var (
 		{Name: "gname", Type: field.TypeString, Comment: "群组名称", Default: ""},
 		{Name: "v3", Type: field.TypeString, Comment: "v3数据", Default: ""},
 	}
-	// ContactTable holds the schema information for the "contact" table.
-	ContactTable = &schema.Table{
-		Name:       "contact",
-		Columns:    ContactColumns,
-		PrimaryKey: []*schema.Column{ContactColumns[0]},
+	// ContactsTable holds the schema information for the "contacts" table.
+	ContactsTable = &schema.Table{
+		Name:       "contacts",
+		Columns:    ContactsColumns,
+		PrimaryKey: []*schema.Column{ContactsColumns[0]},
 		Indexes: []*schema.Index{
 			{
 				Name:    "contact_wx_wxid_wxid",
 				Unique:  true,
-				Columns: []*schema.Column{ContactColumns[5], ContactColumns[7]},
+				Columns: []*schema.Column{ContactsColumns[5], ContactsColumns[7]},
 			},
 			{
 				Name:    "contact_wxid",
 				Unique:  false,
-				Columns: []*schema.Column{ContactColumns[7]},
+				Columns: []*schema.Column{ContactsColumns[7]},
 			},
 			{
 				Name:    "contact_type",
 				Unique:  false,
-				Columns: []*schema.Column{ContactColumns[6]},
+				Columns: []*schema.Column{ContactsColumns[6]},
 			},
 			{
 				Name:    "contact_gid",
 				Unique:  false,
-				Columns: []*schema.Column{ContactColumns[17]},
+				Columns: []*schema.Column{ContactsColumns[17]},
 			},
 		},
 	}
-	// LabelColumns holds the columns for the "label" table.
-	LabelColumns = []*schema.Column{
+	// LabelsColumns holds the columns for the "labels" table.
+	LabelsColumns = []*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 | 修改日期"},
@@ -73,21 +103,21 @@ var (
 		{Name: "mode", Type: field.TypeInt, Comment: "标签模式:1动态 2静态", Default: 1},
 		{Name: "conditions", Type: field.TypeString, Nullable: true, Comment: "标签的触达条件", Default: ""},
 	}
-	// LabelTable holds the schema information for the "label" table.
-	LabelTable = &schema.Table{
-		Name:       "label",
-		Columns:    LabelColumns,
-		PrimaryKey: []*schema.Column{LabelColumns[0]},
+	// LabelsTable holds the schema information for the "labels" table.
+	LabelsTable = &schema.Table{
+		Name:       "labels",
+		Columns:    LabelsColumns,
+		PrimaryKey: []*schema.Column{LabelsColumns[0]},
 		Indexes: []*schema.Index{
 			{
 				Name:    "label_name_from_mode",
 				Unique:  true,
-				Columns: []*schema.Column{LabelColumns[6], LabelColumns[7], LabelColumns[8]},
+				Columns: []*schema.Column{LabelsColumns[6], LabelsColumns[7], LabelsColumns[8]},
 			},
 		},
 	}
-	// LabelRelationshipColumns holds the columns for the "label_relationship" table.
-	LabelRelationshipColumns = []*schema.Column{
+	// LabelRelationshipsColumns holds the columns for the "label_relationships" table.
+	LabelRelationshipsColumns = []*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 | 修改日期"},
@@ -96,22 +126,22 @@ var (
 		{Name: "contact_id", Type: field.TypeUint64, Comment: "联系人 ID", Default: 1},
 		{Name: "label_id", Type: field.TypeUint64, Comment: "标签 ID", Default: 1},
 	}
-	// LabelRelationshipTable holds the schema information for the "label_relationship" table.
-	LabelRelationshipTable = &schema.Table{
-		Name:       "label_relationship",
-		Columns:    LabelRelationshipColumns,
-		PrimaryKey: []*schema.Column{LabelRelationshipColumns[0]},
+	// LabelRelationshipsTable holds the schema information for the "label_relationships" table.
+	LabelRelationshipsTable = &schema.Table{
+		Name:       "label_relationships",
+		Columns:    LabelRelationshipsColumns,
+		PrimaryKey: []*schema.Column{LabelRelationshipsColumns[0]},
 		ForeignKeys: []*schema.ForeignKey{
 			{
-				Symbol:     "label_relationship_contact_contact_relationships",
-				Columns:    []*schema.Column{LabelRelationshipColumns[5]},
-				RefColumns: []*schema.Column{ContactColumns[0]},
+				Symbol:     "label_relationships_contacts_contact_relationships",
+				Columns:    []*schema.Column{LabelRelationshipsColumns[5]},
+				RefColumns: []*schema.Column{ContactsColumns[0]},
 				OnDelete:   schema.NoAction,
 			},
 			{
-				Symbol:     "label_relationship_label_label_relationships",
-				Columns:    []*schema.Column{LabelRelationshipColumns[6]},
-				RefColumns: []*schema.Column{LabelColumns[0]},
+				Symbol:     "label_relationships_labels_label_relationships",
+				Columns:    []*schema.Column{LabelRelationshipsColumns[6]},
+				RefColumns: []*schema.Column{LabelsColumns[0]},
 				OnDelete:   schema.NoAction,
 			},
 		},
@@ -119,30 +149,30 @@ var (
 			{
 				Name:    "labelrelationship_label_id",
 				Unique:  false,
-				Columns: []*schema.Column{LabelRelationshipColumns[6]},
+				Columns: []*schema.Column{LabelRelationshipsColumns[6]},
 			},
 			{
 				Name:    "labelrelationship_contact_id",
 				Unique:  false,
-				Columns: []*schema.Column{LabelRelationshipColumns[5]},
+				Columns: []*schema.Column{LabelRelationshipsColumns[5]},
 			},
 		},
 	}
-	// MessageColumns holds the columns for the "message" table.
-	MessageColumns = []*schema.Column{
+	// MessagesColumns holds the columns for the "messages" table.
+	MessagesColumns = []*schema.Column{
 		{Name: "id", Type: field.TypeInt, Increment: true},
 		{Name: "wx_wxid", Type: field.TypeString, Nullable: true, Comment: "属主微信id", Default: ""},
 		{Name: "wxid", Type: field.TypeString, Comment: "微信id 公众号微信ID", Default: ""},
 		{Name: "content", Type: field.TypeString, Comment: "微信消息内容", Default: ""},
 	}
-	// MessageTable holds the schema information for the "message" table.
-	MessageTable = &schema.Table{
-		Name:       "message",
-		Columns:    MessageColumns,
-		PrimaryKey: []*schema.Column{MessageColumns[0]},
+	// MessagesTable holds the schema information for the "messages" table.
+	MessagesTable = &schema.Table{
+		Name:       "messages",
+		Columns:    MessagesColumns,
+		PrimaryKey: []*schema.Column{MessagesColumns[0]},
 	}
-	// MessageRecordsColumns holds the columns for the "message_records" table.
-	MessageRecordsColumns = []*schema.Column{
+	// MessageRecordssColumns holds the columns for the "message_recordss" table.
+	MessageRecordssColumns = []*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 | 修改日期"},
@@ -161,28 +191,28 @@ var (
 		{Name: "sub_source_id", Type: field.TypeUint64, Nullable: true, Comment: "次源 ID", Default: 1},
 		{Name: "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]},
+	// MessageRecordssTable holds the schema information for the "message_recordss" table.
+	MessageRecordssTable = &schema.Table{
+		Name:       "message_recordss",
+		Columns:    MessageRecordssColumns,
+		PrimaryKey: []*schema.Column{MessageRecordssColumns[0]},
 		ForeignKeys: []*schema.ForeignKey{
 			{
-				Symbol:     "message_records_contact_contact_messages",
-				Columns:    []*schema.Column{MessageRecordsColumns[14]},
-				RefColumns: []*schema.Column{ContactColumns[0]},
+				Symbol:     "message_recordss_contacts_contact_messages",
+				Columns:    []*schema.Column{MessageRecordssColumns[14]},
+				RefColumns: []*schema.Column{ContactsColumns[0]},
 				OnDelete:   schema.SetNull,
 			},
 			{
-				Symbol:     "message_records_sop_node_node_messages",
-				Columns:    []*schema.Column{MessageRecordsColumns[15]},
-				RefColumns: []*schema.Column{SopNodeColumns[0]},
+				Symbol:     "message_recordss_sop_nodes_node_messages",
+				Columns:    []*schema.Column{MessageRecordssColumns[15]},
+				RefColumns: []*schema.Column{SopNodesColumns[0]},
 				OnDelete:   schema.SetNull,
 			},
 			{
-				Symbol:     "message_records_sop_stage_stage_messages",
-				Columns:    []*schema.Column{MessageRecordsColumns[16]},
-				RefColumns: []*schema.Column{SopStageColumns[0]},
+				Symbol:     "message_recordss_sop_stages_stage_messages",
+				Columns:    []*schema.Column{MessageRecordssColumns[16]},
+				RefColumns: []*schema.Column{SopStagesColumns[0]},
 				OnDelete:   schema.SetNull,
 			},
 		},
@@ -190,12 +220,12 @@ var (
 			{
 				Name:    "messagerecords_source_type",
 				Unique:  false,
-				Columns: []*schema.Column{MessageRecordsColumns[13]},
+				Columns: []*schema.Column{MessageRecordssColumns[13]},
 			},
 		},
 	}
-	// ServerColumns holds the columns for the "server" table.
-	ServerColumns = []*schema.Column{
+	// ServersColumns holds the columns for the "servers" table.
+	ServersColumns = []*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 | 修改日期"},
@@ -206,31 +236,31 @@ var (
 		{Name: "private_ip", Type: field.TypeString, Comment: "内网ip"},
 		{Name: "admin_port", Type: field.TypeString, Comment: "管理端口"},
 	}
-	// ServerTable holds the schema information for the "server" table.
-	ServerTable = &schema.Table{
-		Name:       "server",
-		Columns:    ServerColumns,
-		PrimaryKey: []*schema.Column{ServerColumns[0]},
+	// ServersTable holds the schema information for the "servers" table.
+	ServersTable = &schema.Table{
+		Name:       "servers",
+		Columns:    ServersColumns,
+		PrimaryKey: []*schema.Column{ServersColumns[0]},
 		Indexes: []*schema.Index{
 			{
 				Name:    "server_name",
 				Unique:  false,
-				Columns: []*schema.Column{ServerColumns[5]},
+				Columns: []*schema.Column{ServersColumns[5]},
 			},
 			{
 				Name:    "server_private_ip",
 				Unique:  false,
-				Columns: []*schema.Column{ServerColumns[7]},
+				Columns: []*schema.Column{ServersColumns[7]},
 			},
 			{
 				Name:    "server_public_ip",
 				Unique:  true,
-				Columns: []*schema.Column{ServerColumns[6]},
+				Columns: []*schema.Column{ServersColumns[6]},
 			},
 		},
 	}
-	// SopNodeColumns holds the columns for the "sop_node" table.
-	SopNodeColumns = []*schema.Column{
+	// SopNodesColumns holds the columns for the "sop_nodes" table.
+	SopNodesColumns = []*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 | 修改日期"},
@@ -245,16 +275,16 @@ var (
 		{Name: "action_label", Type: field.TypeJSON, Nullable: true, Comment: "命中后需要打的标签"},
 		{Name: "stage_id", Type: field.TypeUint64, Comment: "阶段 ID"},
 	}
-	// SopNodeTable holds the schema information for the "sop_node" table.
-	SopNodeTable = &schema.Table{
-		Name:       "sop_node",
-		Columns:    SopNodeColumns,
-		PrimaryKey: []*schema.Column{SopNodeColumns[0]},
+	// SopNodesTable holds the schema information for the "sop_nodes" table.
+	SopNodesTable = &schema.Table{
+		Name:       "sop_nodes",
+		Columns:    SopNodesColumns,
+		PrimaryKey: []*schema.Column{SopNodesColumns[0]},
 		ForeignKeys: []*schema.ForeignKey{
 			{
-				Symbol:     "sop_node_sop_stage_stage_nodes",
-				Columns:    []*schema.Column{SopNodeColumns[12]},
-				RefColumns: []*schema.Column{SopStageColumns[0]},
+				Symbol:     "sop_nodes_sop_stages_stage_nodes",
+				Columns:    []*schema.Column{SopNodesColumns[12]},
+				RefColumns: []*schema.Column{SopStagesColumns[0]},
 				OnDelete:   schema.NoAction,
 			},
 		},
@@ -262,12 +292,12 @@ var (
 			{
 				Name:    "sopnode_name",
 				Unique:  false,
-				Columns: []*schema.Column{SopNodeColumns[6]},
+				Columns: []*schema.Column{SopNodesColumns[6]},
 			},
 		},
 	}
-	// SopStageColumns holds the columns for the "sop_stage" table.
-	SopStageColumns = []*schema.Column{
+	// SopStagesColumns holds the columns for the "sop_stages" table.
+	SopStagesColumns = []*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 | 修改日期"},
@@ -282,16 +312,16 @@ var (
 		{Name: "index_sort", Type: field.TypeInt, Nullable: true, Comment: "阶段顺序", Default: 1},
 		{Name: "task_id", Type: field.TypeUint64, Comment: "SOP 任务 ID"},
 	}
-	// SopStageTable holds the schema information for the "sop_stage" table.
-	SopStageTable = &schema.Table{
-		Name:       "sop_stage",
-		Columns:    SopStageColumns,
-		PrimaryKey: []*schema.Column{SopStageColumns[0]},
+	// SopStagesTable holds the schema information for the "sop_stages" table.
+	SopStagesTable = &schema.Table{
+		Name:       "sop_stages",
+		Columns:    SopStagesColumns,
+		PrimaryKey: []*schema.Column{SopStagesColumns[0]},
 		ForeignKeys: []*schema.ForeignKey{
 			{
-				Symbol:     "sop_stage_sop_task_task_stages",
-				Columns:    []*schema.Column{SopStageColumns[12]},
-				RefColumns: []*schema.Column{SopTaskColumns[0]},
+				Symbol:     "sop_stages_sop_tasks_task_stages",
+				Columns:    []*schema.Column{SopStagesColumns[12]},
+				RefColumns: []*schema.Column{SopTasksColumns[0]},
 				OnDelete:   schema.NoAction,
 			},
 		},
@@ -299,12 +329,12 @@ var (
 			{
 				Name:    "sopstage_name",
 				Unique:  false,
-				Columns: []*schema.Column{SopStageColumns[5]},
+				Columns: []*schema.Column{SopStagesColumns[5]},
 			},
 		},
 	}
-	// SopTaskColumns holds the columns for the "sop_task" table.
-	SopTaskColumns = []*schema.Column{
+	// SopTasksColumns holds the columns for the "sop_tasks" table.
+	SopTasksColumns = []*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 | 修改日期"},
@@ -317,21 +347,21 @@ var (
 		{Name: "plan_end_time", Type: field.TypeTime, Nullable: true, Comment: "任务计划结束时间"},
 		{Name: "creator_id", Type: field.TypeString, Nullable: true, Comment: "创建者 id"},
 	}
-	// SopTaskTable holds the schema information for the "sop_task" table.
-	SopTaskTable = &schema.Table{
-		Name:       "sop_task",
-		Columns:    SopTaskColumns,
-		PrimaryKey: []*schema.Column{SopTaskColumns[0]},
+	// SopTasksTable holds the schema information for the "sop_tasks" table.
+	SopTasksTable = &schema.Table{
+		Name:       "sop_tasks",
+		Columns:    SopTasksColumns,
+		PrimaryKey: []*schema.Column{SopTasksColumns[0]},
 		Indexes: []*schema.Index{
 			{
 				Name:    "soptask_name",
 				Unique:  false,
-				Columns: []*schema.Column{SopTaskColumns[5]},
+				Columns: []*schema.Column{SopTasksColumns[5]},
 			},
 		},
 	}
-	// WxColumns holds the columns for the "wx" table.
-	WxColumns = []*schema.Column{
+	// WxsColumns holds the columns for the "wxs" table.
+	WxsColumns = []*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 | 修改日期"},
@@ -347,16 +377,16 @@ var (
 		{Name: "head_big", Type: field.TypeString, Comment: "微信头像", Default: ""},
 		{Name: "server_id", Type: field.TypeUint64, Nullable: true, Comment: "服务器id", Default: 0},
 	}
-	// WxTable holds the schema information for the "wx" table.
-	WxTable = &schema.Table{
-		Name:       "wx",
-		Columns:    WxColumns,
-		PrimaryKey: []*schema.Column{WxColumns[0]},
+	// WxsTable holds the schema information for the "wxs" table.
+	WxsTable = &schema.Table{
+		Name:       "wxs",
+		Columns:    WxsColumns,
+		PrimaryKey: []*schema.Column{WxsColumns[0]},
 		ForeignKeys: []*schema.ForeignKey{
 			{
-				Symbol:     "wx_server_wxs",
-				Columns:    []*schema.Column{WxColumns[13]},
-				RefColumns: []*schema.Column{ServerColumns[0]},
+				Symbol:     "wxs_servers_wxs",
+				Columns:    []*schema.Column{WxsColumns[13]},
+				RefColumns: []*schema.Column{ServersColumns[0]},
 				OnDelete:   schema.SetNull,
 			},
 		},
@@ -364,82 +394,86 @@ var (
 			{
 				Name:    "wx_server_id_port",
 				Unique:  true,
-				Columns: []*schema.Column{WxColumns[13], WxColumns[5]},
+				Columns: []*schema.Column{WxsColumns[13], WxsColumns[5]},
 			},
 			{
 				Name:    "wx_wxid",
 				Unique:  true,
-				Columns: []*schema.Column{WxColumns[8]},
+				Columns: []*schema.Column{WxsColumns[8]},
 			},
 			{
 				Name:    "wx_account",
 				Unique:  false,
-				Columns: []*schema.Column{WxColumns[9]},
+				Columns: []*schema.Column{WxsColumns[9]},
 			},
 			{
 				Name:    "wx_nickname",
 				Unique:  false,
-				Columns: []*schema.Column{WxColumns[10]},
+				Columns: []*schema.Column{WxsColumns[10]},
 			},
 			{
 				Name:    "wx_tel",
 				Unique:  false,
-				Columns: []*schema.Column{WxColumns[11]},
+				Columns: []*schema.Column{WxsColumns[11]},
 			},
 		},
 	}
 	// Tables holds all the tables in the schema.
 	Tables = []*schema.Table{
-		ContactTable,
-		LabelTable,
-		LabelRelationshipTable,
-		MessageTable,
-		MessageRecordsTable,
-		ServerTable,
-		SopNodeTable,
-		SopStageTable,
-		SopTaskTable,
-		WxTable,
+		BatchMsgsTable,
+		ContactsTable,
+		LabelsTable,
+		LabelRelationshipsTable,
+		MessagesTable,
+		MessageRecordssTable,
+		ServersTable,
+		SopNodesTable,
+		SopStagesTable,
+		SopTasksTable,
+		WxsTable,
 	}
 )
 
 func init() {
-	ContactTable.Annotation = &entsql.Annotation{
-		Table: "contact",
+	BatchMsgsTable.Annotation = &entsql.Annotation{
+		Table: "batch_msgs",
+	}
+	ContactsTable.Annotation = &entsql.Annotation{
+		Table: "contacts",
 	}
-	LabelTable.Annotation = &entsql.Annotation{
-		Table: "label",
+	LabelsTable.Annotation = &entsql.Annotation{
+		Table: "labels",
 	}
-	LabelRelationshipTable.ForeignKeys[0].RefTable = ContactTable
-	LabelRelationshipTable.ForeignKeys[1].RefTable = LabelTable
-	LabelRelationshipTable.Annotation = &entsql.Annotation{
-		Table: "label_relationship",
+	LabelRelationshipsTable.ForeignKeys[0].RefTable = ContactsTable
+	LabelRelationshipsTable.ForeignKeys[1].RefTable = LabelsTable
+	LabelRelationshipsTable.Annotation = &entsql.Annotation{
+		Table: "label_relationships",
 	}
-	MessageTable.Annotation = &entsql.Annotation{
-		Table: "message",
+	MessagesTable.Annotation = &entsql.Annotation{
+		Table: "messages",
 	}
-	MessageRecordsTable.ForeignKeys[0].RefTable = ContactTable
-	MessageRecordsTable.ForeignKeys[1].RefTable = SopNodeTable
-	MessageRecordsTable.ForeignKeys[2].RefTable = SopStageTable
-	MessageRecordsTable.Annotation = &entsql.Annotation{
-		Table: "message_records",
+	MessageRecordssTable.ForeignKeys[0].RefTable = ContactsTable
+	MessageRecordssTable.ForeignKeys[1].RefTable = SopNodesTable
+	MessageRecordssTable.ForeignKeys[2].RefTable = SopStagesTable
+	MessageRecordssTable.Annotation = &entsql.Annotation{
+		Table: "message_recordss",
 	}
-	ServerTable.Annotation = &entsql.Annotation{
-		Table: "server",
+	ServersTable.Annotation = &entsql.Annotation{
+		Table: "servers",
 	}
-	SopNodeTable.ForeignKeys[0].RefTable = SopStageTable
-	SopNodeTable.Annotation = &entsql.Annotation{
-		Table: "sop_node",
+	SopNodesTable.ForeignKeys[0].RefTable = SopStagesTable
+	SopNodesTable.Annotation = &entsql.Annotation{
+		Table: "sop_nodes",
 	}
-	SopStageTable.ForeignKeys[0].RefTable = SopTaskTable
-	SopStageTable.Annotation = &entsql.Annotation{
-		Table: "sop_stage",
+	SopStagesTable.ForeignKeys[0].RefTable = SopTasksTable
+	SopStagesTable.Annotation = &entsql.Annotation{
+		Table: "sop_stages",
 	}
-	SopTaskTable.Annotation = &entsql.Annotation{
-		Table: "sop_task",
+	SopTasksTable.Annotation = &entsql.Annotation{
+		Table: "sop_tasks",
 	}
-	WxTable.ForeignKeys[0].RefTable = ServerTable
-	WxTable.Annotation = &entsql.Annotation{
-		Table: "wx",
+	WxsTable.ForeignKeys[0].RefTable = ServersTable
+	WxsTable.Annotation = &entsql.Annotation{
+		Table: "wxs",
 	}
 }

+ 1333 - 0
ent/mutation.go

@@ -8,6 +8,7 @@ import (
 	"fmt"
 	"sync"
 	"time"
+	"wechat-api/ent/batchmsg"
 	"wechat-api/ent/contact"
 	"wechat-api/ent/custom_types"
 	"wechat-api/ent/label"
@@ -34,6 +35,7 @@ const (
 	OpUpdateOne = ent.OpUpdateOne
 
 	// Node types.
+	TypeBatchMsg          = "BatchMsg"
 	TypeContact           = "Contact"
 	TypeLabel             = "Label"
 	TypeLabelRelationship = "LabelRelationship"
@@ -46,6 +48,1337 @@ const (
 	TypeWx                = "Wx"
 )
 
+// BatchMsgMutation represents an operation that mutates the BatchMsg nodes in the graph.
+type BatchMsgMutation struct {
+	config
+	op            Op
+	typ           string
+	id            *uint64
+	created_at    *time.Time
+	updated_at    *time.Time
+	deleted_at    *time.Time
+	status        *uint8
+	addstatus     *int8
+	batch_no      *string
+	fromwxid      *string
+	msg           *string
+	tag           *string
+	total         *int32
+	addtotal      *int32
+	success       *int32
+	addsuccess    *int32
+	fail          *int32
+	addfail       *int32
+	start_time    *time.Time
+	stop_time     *time.Time
+	clearedFields map[string]struct{}
+	done          bool
+	oldValue      func(context.Context) (*BatchMsg, error)
+	predicates    []predicate.BatchMsg
+}
+
+var _ ent.Mutation = (*BatchMsgMutation)(nil)
+
+// batchmsgOption allows management of the mutation configuration using functional options.
+type batchmsgOption func(*BatchMsgMutation)
+
+// newBatchMsgMutation creates new mutation for the BatchMsg entity.
+func newBatchMsgMutation(c config, op Op, opts ...batchmsgOption) *BatchMsgMutation {
+	m := &BatchMsgMutation{
+		config:        c,
+		op:            op,
+		typ:           TypeBatchMsg,
+		clearedFields: make(map[string]struct{}),
+	}
+	for _, opt := range opts {
+		opt(m)
+	}
+	return m
+}
+
+// withBatchMsgID sets the ID field of the mutation.
+func withBatchMsgID(id uint64) batchmsgOption {
+	return func(m *BatchMsgMutation) {
+		var (
+			err   error
+			once  sync.Once
+			value *BatchMsg
+		)
+		m.oldValue = func(ctx context.Context) (*BatchMsg, error) {
+			once.Do(func() {
+				if m.done {
+					err = errors.New("querying old values post mutation is not allowed")
+				} else {
+					value, err = m.Client().BatchMsg.Get(ctx, id)
+				}
+			})
+			return value, err
+		}
+		m.id = &id
+	}
+}
+
+// withBatchMsg sets the old BatchMsg of the mutation.
+func withBatchMsg(node *BatchMsg) batchmsgOption {
+	return func(m *BatchMsgMutation) {
+		m.oldValue = func(context.Context) (*BatchMsg, 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 BatchMsgMutation) 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 BatchMsgMutation) 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 BatchMsg entities.
+func (m *BatchMsgMutation) 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 *BatchMsgMutation) 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 *BatchMsgMutation) 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().BatchMsg.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 *BatchMsgMutation) SetCreatedAt(t time.Time) {
+	m.created_at = &t
+}
+
+// CreatedAt returns the value of the "created_at" field in the mutation.
+func (m *BatchMsgMutation) 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 BatchMsg entity.
+// If the BatchMsg 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 *BatchMsgMutation) 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 *BatchMsgMutation) ResetCreatedAt() {
+	m.created_at = nil
+}
+
+// SetUpdatedAt sets the "updated_at" field.
+func (m *BatchMsgMutation) SetUpdatedAt(t time.Time) {
+	m.updated_at = &t
+}
+
+// UpdatedAt returns the value of the "updated_at" field in the mutation.
+func (m *BatchMsgMutation) 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 BatchMsg entity.
+// If the BatchMsg 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 *BatchMsgMutation) 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 *BatchMsgMutation) ResetUpdatedAt() {
+	m.updated_at = nil
+}
+
+// SetDeletedAt sets the "deleted_at" field.
+func (m *BatchMsgMutation) SetDeletedAt(t time.Time) {
+	m.deleted_at = &t
+}
+
+// DeletedAt returns the value of the "deleted_at" field in the mutation.
+func (m *BatchMsgMutation) DeletedAt() (r time.Time, exists bool) {
+	v := m.deleted_at
+	if v == nil {
+		return
+	}
+	return *v, true
+}
+
+// OldDeletedAt returns the old "deleted_at" field's value of the BatchMsg entity.
+// If the BatchMsg 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 *BatchMsgMutation) OldDeletedAt(ctx context.Context) (v time.Time, err error) {
+	if !m.op.Is(OpUpdateOne) {
+		return v, errors.New("OldDeletedAt is only allowed on UpdateOne operations")
+	}
+	if m.id == nil || m.oldValue == nil {
+		return v, errors.New("OldDeletedAt requires an ID field in the mutation")
+	}
+	oldValue, err := m.oldValue(ctx)
+	if err != nil {
+		return v, fmt.Errorf("querying old value for OldDeletedAt: %w", err)
+	}
+	return oldValue.DeletedAt, nil
+}
+
+// ClearDeletedAt clears the value of the "deleted_at" field.
+func (m *BatchMsgMutation) ClearDeletedAt() {
+	m.deleted_at = nil
+	m.clearedFields[batchmsg.FieldDeletedAt] = struct{}{}
+}
+
+// DeletedAtCleared returns if the "deleted_at" field was cleared in this mutation.
+func (m *BatchMsgMutation) DeletedAtCleared() bool {
+	_, ok := m.clearedFields[batchmsg.FieldDeletedAt]
+	return ok
+}
+
+// ResetDeletedAt resets all changes to the "deleted_at" field.
+func (m *BatchMsgMutation) ResetDeletedAt() {
+	m.deleted_at = nil
+	delete(m.clearedFields, batchmsg.FieldDeletedAt)
+}
+
+// SetStatus sets the "status" field.
+func (m *BatchMsgMutation) SetStatus(u uint8) {
+	m.status = &u
+	m.addstatus = nil
+}
+
+// Status returns the value of the "status" field in the mutation.
+func (m *BatchMsgMutation) 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 BatchMsg entity.
+// If the BatchMsg 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 *BatchMsgMutation) 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 *BatchMsgMutation) 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 *BatchMsgMutation) 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 *BatchMsgMutation) ClearStatus() {
+	m.status = nil
+	m.addstatus = nil
+	m.clearedFields[batchmsg.FieldStatus] = struct{}{}
+}
+
+// StatusCleared returns if the "status" field was cleared in this mutation.
+func (m *BatchMsgMutation) StatusCleared() bool {
+	_, ok := m.clearedFields[batchmsg.FieldStatus]
+	return ok
+}
+
+// ResetStatus resets all changes to the "status" field.
+func (m *BatchMsgMutation) ResetStatus() {
+	m.status = nil
+	m.addstatus = nil
+	delete(m.clearedFields, batchmsg.FieldStatus)
+}
+
+// SetBatchNo sets the "batch_no" field.
+func (m *BatchMsgMutation) SetBatchNo(s string) {
+	m.batch_no = &s
+}
+
+// BatchNo returns the value of the "batch_no" field in the mutation.
+func (m *BatchMsgMutation) BatchNo() (r string, exists bool) {
+	v := m.batch_no
+	if v == nil {
+		return
+	}
+	return *v, true
+}
+
+// OldBatchNo returns the old "batch_no" field's value of the BatchMsg entity.
+// If the BatchMsg 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 *BatchMsgMutation) OldBatchNo(ctx context.Context) (v string, err error) {
+	if !m.op.Is(OpUpdateOne) {
+		return v, errors.New("OldBatchNo is only allowed on UpdateOne operations")
+	}
+	if m.id == nil || m.oldValue == nil {
+		return v, errors.New("OldBatchNo requires an ID field in the mutation")
+	}
+	oldValue, err := m.oldValue(ctx)
+	if err != nil {
+		return v, fmt.Errorf("querying old value for OldBatchNo: %w", err)
+	}
+	return oldValue.BatchNo, nil
+}
+
+// ClearBatchNo clears the value of the "batch_no" field.
+func (m *BatchMsgMutation) ClearBatchNo() {
+	m.batch_no = nil
+	m.clearedFields[batchmsg.FieldBatchNo] = struct{}{}
+}
+
+// BatchNoCleared returns if the "batch_no" field was cleared in this mutation.
+func (m *BatchMsgMutation) BatchNoCleared() bool {
+	_, ok := m.clearedFields[batchmsg.FieldBatchNo]
+	return ok
+}
+
+// ResetBatchNo resets all changes to the "batch_no" field.
+func (m *BatchMsgMutation) ResetBatchNo() {
+	m.batch_no = nil
+	delete(m.clearedFields, batchmsg.FieldBatchNo)
+}
+
+// SetFromwxid sets the "fromwxid" field.
+func (m *BatchMsgMutation) SetFromwxid(s string) {
+	m.fromwxid = &s
+}
+
+// Fromwxid returns the value of the "fromwxid" field in the mutation.
+func (m *BatchMsgMutation) Fromwxid() (r string, exists bool) {
+	v := m.fromwxid
+	if v == nil {
+		return
+	}
+	return *v, true
+}
+
+// OldFromwxid returns the old "fromwxid" field's value of the BatchMsg entity.
+// If the BatchMsg 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 *BatchMsgMutation) OldFromwxid(ctx context.Context) (v string, err error) {
+	if !m.op.Is(OpUpdateOne) {
+		return v, errors.New("OldFromwxid is only allowed on UpdateOne operations")
+	}
+	if m.id == nil || m.oldValue == nil {
+		return v, errors.New("OldFromwxid requires an ID field in the mutation")
+	}
+	oldValue, err := m.oldValue(ctx)
+	if err != nil {
+		return v, fmt.Errorf("querying old value for OldFromwxid: %w", err)
+	}
+	return oldValue.Fromwxid, nil
+}
+
+// ClearFromwxid clears the value of the "fromwxid" field.
+func (m *BatchMsgMutation) ClearFromwxid() {
+	m.fromwxid = nil
+	m.clearedFields[batchmsg.FieldFromwxid] = struct{}{}
+}
+
+// FromwxidCleared returns if the "fromwxid" field was cleared in this mutation.
+func (m *BatchMsgMutation) FromwxidCleared() bool {
+	_, ok := m.clearedFields[batchmsg.FieldFromwxid]
+	return ok
+}
+
+// ResetFromwxid resets all changes to the "fromwxid" field.
+func (m *BatchMsgMutation) ResetFromwxid() {
+	m.fromwxid = nil
+	delete(m.clearedFields, batchmsg.FieldFromwxid)
+}
+
+// SetMsg sets the "msg" field.
+func (m *BatchMsgMutation) SetMsg(s string) {
+	m.msg = &s
+}
+
+// Msg returns the value of the "msg" field in the mutation.
+func (m *BatchMsgMutation) Msg() (r string, exists bool) {
+	v := m.msg
+	if v == nil {
+		return
+	}
+	return *v, true
+}
+
+// OldMsg returns the old "msg" field's value of the BatchMsg entity.
+// If the BatchMsg 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 *BatchMsgMutation) OldMsg(ctx context.Context) (v string, err error) {
+	if !m.op.Is(OpUpdateOne) {
+		return v, errors.New("OldMsg is only allowed on UpdateOne operations")
+	}
+	if m.id == nil || m.oldValue == nil {
+		return v, errors.New("OldMsg requires an ID field in the mutation")
+	}
+	oldValue, err := m.oldValue(ctx)
+	if err != nil {
+		return v, fmt.Errorf("querying old value for OldMsg: %w", err)
+	}
+	return oldValue.Msg, nil
+}
+
+// ClearMsg clears the value of the "msg" field.
+func (m *BatchMsgMutation) ClearMsg() {
+	m.msg = nil
+	m.clearedFields[batchmsg.FieldMsg] = struct{}{}
+}
+
+// MsgCleared returns if the "msg" field was cleared in this mutation.
+func (m *BatchMsgMutation) MsgCleared() bool {
+	_, ok := m.clearedFields[batchmsg.FieldMsg]
+	return ok
+}
+
+// ResetMsg resets all changes to the "msg" field.
+func (m *BatchMsgMutation) ResetMsg() {
+	m.msg = nil
+	delete(m.clearedFields, batchmsg.FieldMsg)
+}
+
+// SetTag sets the "tag" field.
+func (m *BatchMsgMutation) SetTag(s string) {
+	m.tag = &s
+}
+
+// Tag returns the value of the "tag" field in the mutation.
+func (m *BatchMsgMutation) Tag() (r string, exists bool) {
+	v := m.tag
+	if v == nil {
+		return
+	}
+	return *v, true
+}
+
+// OldTag returns the old "tag" field's value of the BatchMsg entity.
+// If the BatchMsg 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 *BatchMsgMutation) OldTag(ctx context.Context) (v string, err error) {
+	if !m.op.Is(OpUpdateOne) {
+		return v, errors.New("OldTag is only allowed on UpdateOne operations")
+	}
+	if m.id == nil || m.oldValue == nil {
+		return v, errors.New("OldTag requires an ID field in the mutation")
+	}
+	oldValue, err := m.oldValue(ctx)
+	if err != nil {
+		return v, fmt.Errorf("querying old value for OldTag: %w", err)
+	}
+	return oldValue.Tag, nil
+}
+
+// ClearTag clears the value of the "tag" field.
+func (m *BatchMsgMutation) ClearTag() {
+	m.tag = nil
+	m.clearedFields[batchmsg.FieldTag] = struct{}{}
+}
+
+// TagCleared returns if the "tag" field was cleared in this mutation.
+func (m *BatchMsgMutation) TagCleared() bool {
+	_, ok := m.clearedFields[batchmsg.FieldTag]
+	return ok
+}
+
+// ResetTag resets all changes to the "tag" field.
+func (m *BatchMsgMutation) ResetTag() {
+	m.tag = nil
+	delete(m.clearedFields, batchmsg.FieldTag)
+}
+
+// SetTotal sets the "total" field.
+func (m *BatchMsgMutation) SetTotal(i int32) {
+	m.total = &i
+	m.addtotal = nil
+}
+
+// Total returns the value of the "total" field in the mutation.
+func (m *BatchMsgMutation) Total() (r int32, exists bool) {
+	v := m.total
+	if v == nil {
+		return
+	}
+	return *v, true
+}
+
+// OldTotal returns the old "total" field's value of the BatchMsg entity.
+// If the BatchMsg 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 *BatchMsgMutation) OldTotal(ctx context.Context) (v int32, err error) {
+	if !m.op.Is(OpUpdateOne) {
+		return v, errors.New("OldTotal is only allowed on UpdateOne operations")
+	}
+	if m.id == nil || m.oldValue == nil {
+		return v, errors.New("OldTotal requires an ID field in the mutation")
+	}
+	oldValue, err := m.oldValue(ctx)
+	if err != nil {
+		return v, fmt.Errorf("querying old value for OldTotal: %w", err)
+	}
+	return oldValue.Total, nil
+}
+
+// AddTotal adds i to the "total" field.
+func (m *BatchMsgMutation) AddTotal(i int32) {
+	if m.addtotal != nil {
+		*m.addtotal += i
+	} else {
+		m.addtotal = &i
+	}
+}
+
+// AddedTotal returns the value that was added to the "total" field in this mutation.
+func (m *BatchMsgMutation) AddedTotal() (r int32, exists bool) {
+	v := m.addtotal
+	if v == nil {
+		return
+	}
+	return *v, true
+}
+
+// ClearTotal clears the value of the "total" field.
+func (m *BatchMsgMutation) ClearTotal() {
+	m.total = nil
+	m.addtotal = nil
+	m.clearedFields[batchmsg.FieldTotal] = struct{}{}
+}
+
+// TotalCleared returns if the "total" field was cleared in this mutation.
+func (m *BatchMsgMutation) TotalCleared() bool {
+	_, ok := m.clearedFields[batchmsg.FieldTotal]
+	return ok
+}
+
+// ResetTotal resets all changes to the "total" field.
+func (m *BatchMsgMutation) ResetTotal() {
+	m.total = nil
+	m.addtotal = nil
+	delete(m.clearedFields, batchmsg.FieldTotal)
+}
+
+// SetSuccess sets the "success" field.
+func (m *BatchMsgMutation) SetSuccess(i int32) {
+	m.success = &i
+	m.addsuccess = nil
+}
+
+// Success returns the value of the "success" field in the mutation.
+func (m *BatchMsgMutation) Success() (r int32, exists bool) {
+	v := m.success
+	if v == nil {
+		return
+	}
+	return *v, true
+}
+
+// OldSuccess returns the old "success" field's value of the BatchMsg entity.
+// If the BatchMsg 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 *BatchMsgMutation) OldSuccess(ctx context.Context) (v int32, err error) {
+	if !m.op.Is(OpUpdateOne) {
+		return v, errors.New("OldSuccess is only allowed on UpdateOne operations")
+	}
+	if m.id == nil || m.oldValue == nil {
+		return v, errors.New("OldSuccess requires an ID field in the mutation")
+	}
+	oldValue, err := m.oldValue(ctx)
+	if err != nil {
+		return v, fmt.Errorf("querying old value for OldSuccess: %w", err)
+	}
+	return oldValue.Success, nil
+}
+
+// AddSuccess adds i to the "success" field.
+func (m *BatchMsgMutation) AddSuccess(i int32) {
+	if m.addsuccess != nil {
+		*m.addsuccess += i
+	} else {
+		m.addsuccess = &i
+	}
+}
+
+// AddedSuccess returns the value that was added to the "success" field in this mutation.
+func (m *BatchMsgMutation) AddedSuccess() (r int32, exists bool) {
+	v := m.addsuccess
+	if v == nil {
+		return
+	}
+	return *v, true
+}
+
+// ClearSuccess clears the value of the "success" field.
+func (m *BatchMsgMutation) ClearSuccess() {
+	m.success = nil
+	m.addsuccess = nil
+	m.clearedFields[batchmsg.FieldSuccess] = struct{}{}
+}
+
+// SuccessCleared returns if the "success" field was cleared in this mutation.
+func (m *BatchMsgMutation) SuccessCleared() bool {
+	_, ok := m.clearedFields[batchmsg.FieldSuccess]
+	return ok
+}
+
+// ResetSuccess resets all changes to the "success" field.
+func (m *BatchMsgMutation) ResetSuccess() {
+	m.success = nil
+	m.addsuccess = nil
+	delete(m.clearedFields, batchmsg.FieldSuccess)
+}
+
+// SetFail sets the "fail" field.
+func (m *BatchMsgMutation) SetFail(i int32) {
+	m.fail = &i
+	m.addfail = nil
+}
+
+// Fail returns the value of the "fail" field in the mutation.
+func (m *BatchMsgMutation) Fail() (r int32, exists bool) {
+	v := m.fail
+	if v == nil {
+		return
+	}
+	return *v, true
+}
+
+// OldFail returns the old "fail" field's value of the BatchMsg entity.
+// If the BatchMsg 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 *BatchMsgMutation) OldFail(ctx context.Context) (v int32, err error) {
+	if !m.op.Is(OpUpdateOne) {
+		return v, errors.New("OldFail is only allowed on UpdateOne operations")
+	}
+	if m.id == nil || m.oldValue == nil {
+		return v, errors.New("OldFail requires an ID field in the mutation")
+	}
+	oldValue, err := m.oldValue(ctx)
+	if err != nil {
+		return v, fmt.Errorf("querying old value for OldFail: %w", err)
+	}
+	return oldValue.Fail, nil
+}
+
+// AddFail adds i to the "fail" field.
+func (m *BatchMsgMutation) AddFail(i int32) {
+	if m.addfail != nil {
+		*m.addfail += i
+	} else {
+		m.addfail = &i
+	}
+}
+
+// AddedFail returns the value that was added to the "fail" field in this mutation.
+func (m *BatchMsgMutation) AddedFail() (r int32, exists bool) {
+	v := m.addfail
+	if v == nil {
+		return
+	}
+	return *v, true
+}
+
+// ClearFail clears the value of the "fail" field.
+func (m *BatchMsgMutation) ClearFail() {
+	m.fail = nil
+	m.addfail = nil
+	m.clearedFields[batchmsg.FieldFail] = struct{}{}
+}
+
+// FailCleared returns if the "fail" field was cleared in this mutation.
+func (m *BatchMsgMutation) FailCleared() bool {
+	_, ok := m.clearedFields[batchmsg.FieldFail]
+	return ok
+}
+
+// ResetFail resets all changes to the "fail" field.
+func (m *BatchMsgMutation) ResetFail() {
+	m.fail = nil
+	m.addfail = nil
+	delete(m.clearedFields, batchmsg.FieldFail)
+}
+
+// SetStartTime sets the "start_time" field.
+func (m *BatchMsgMutation) SetStartTime(t time.Time) {
+	m.start_time = &t
+}
+
+// StartTime returns the value of the "start_time" field in the mutation.
+func (m *BatchMsgMutation) StartTime() (r time.Time, exists bool) {
+	v := m.start_time
+	if v == nil {
+		return
+	}
+	return *v, true
+}
+
+// OldStartTime returns the old "start_time" field's value of the BatchMsg entity.
+// If the BatchMsg 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 *BatchMsgMutation) OldStartTime(ctx context.Context) (v time.Time, err error) {
+	if !m.op.Is(OpUpdateOne) {
+		return v, errors.New("OldStartTime is only allowed on UpdateOne operations")
+	}
+	if m.id == nil || m.oldValue == nil {
+		return v, errors.New("OldStartTime requires an ID field in the mutation")
+	}
+	oldValue, err := m.oldValue(ctx)
+	if err != nil {
+		return v, fmt.Errorf("querying old value for OldStartTime: %w", err)
+	}
+	return oldValue.StartTime, nil
+}
+
+// ClearStartTime clears the value of the "start_time" field.
+func (m *BatchMsgMutation) ClearStartTime() {
+	m.start_time = nil
+	m.clearedFields[batchmsg.FieldStartTime] = struct{}{}
+}
+
+// StartTimeCleared returns if the "start_time" field was cleared in this mutation.
+func (m *BatchMsgMutation) StartTimeCleared() bool {
+	_, ok := m.clearedFields[batchmsg.FieldStartTime]
+	return ok
+}
+
+// ResetStartTime resets all changes to the "start_time" field.
+func (m *BatchMsgMutation) ResetStartTime() {
+	m.start_time = nil
+	delete(m.clearedFields, batchmsg.FieldStartTime)
+}
+
+// SetStopTime sets the "stop_time" field.
+func (m *BatchMsgMutation) SetStopTime(t time.Time) {
+	m.stop_time = &t
+}
+
+// StopTime returns the value of the "stop_time" field in the mutation.
+func (m *BatchMsgMutation) StopTime() (r time.Time, exists bool) {
+	v := m.stop_time
+	if v == nil {
+		return
+	}
+	return *v, true
+}
+
+// OldStopTime returns the old "stop_time" field's value of the BatchMsg entity.
+// If the BatchMsg 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 *BatchMsgMutation) OldStopTime(ctx context.Context) (v time.Time, err error) {
+	if !m.op.Is(OpUpdateOne) {
+		return v, errors.New("OldStopTime is only allowed on UpdateOne operations")
+	}
+	if m.id == nil || m.oldValue == nil {
+		return v, errors.New("OldStopTime requires an ID field in the mutation")
+	}
+	oldValue, err := m.oldValue(ctx)
+	if err != nil {
+		return v, fmt.Errorf("querying old value for OldStopTime: %w", err)
+	}
+	return oldValue.StopTime, nil
+}
+
+// ClearStopTime clears the value of the "stop_time" field.
+func (m *BatchMsgMutation) ClearStopTime() {
+	m.stop_time = nil
+	m.clearedFields[batchmsg.FieldStopTime] = struct{}{}
+}
+
+// StopTimeCleared returns if the "stop_time" field was cleared in this mutation.
+func (m *BatchMsgMutation) StopTimeCleared() bool {
+	_, ok := m.clearedFields[batchmsg.FieldStopTime]
+	return ok
+}
+
+// ResetStopTime resets all changes to the "stop_time" field.
+func (m *BatchMsgMutation) ResetStopTime() {
+	m.stop_time = nil
+	delete(m.clearedFields, batchmsg.FieldStopTime)
+}
+
+// Where appends a list predicates to the BatchMsgMutation builder.
+func (m *BatchMsgMutation) Where(ps ...predicate.BatchMsg) {
+	m.predicates = append(m.predicates, ps...)
+}
+
+// WhereP appends storage-level predicates to the BatchMsgMutation builder. Using this method,
+// users can use type-assertion to append predicates that do not depend on any generated package.
+func (m *BatchMsgMutation) WhereP(ps ...func(*sql.Selector)) {
+	p := make([]predicate.BatchMsg, len(ps))
+	for i := range ps {
+		p[i] = ps[i]
+	}
+	m.Where(p...)
+}
+
+// Op returns the operation name.
+func (m *BatchMsgMutation) Op() Op {
+	return m.op
+}
+
+// SetOp allows setting the mutation operation.
+func (m *BatchMsgMutation) SetOp(op Op) {
+	m.op = op
+}
+
+// Type returns the node type of this mutation (BatchMsg).
+func (m *BatchMsgMutation) 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 *BatchMsgMutation) Fields() []string {
+	fields := make([]string, 0, 13)
+	if m.created_at != nil {
+		fields = append(fields, batchmsg.FieldCreatedAt)
+	}
+	if m.updated_at != nil {
+		fields = append(fields, batchmsg.FieldUpdatedAt)
+	}
+	if m.deleted_at != nil {
+		fields = append(fields, batchmsg.FieldDeletedAt)
+	}
+	if m.status != nil {
+		fields = append(fields, batchmsg.FieldStatus)
+	}
+	if m.batch_no != nil {
+		fields = append(fields, batchmsg.FieldBatchNo)
+	}
+	if m.fromwxid != nil {
+		fields = append(fields, batchmsg.FieldFromwxid)
+	}
+	if m.msg != nil {
+		fields = append(fields, batchmsg.FieldMsg)
+	}
+	if m.tag != nil {
+		fields = append(fields, batchmsg.FieldTag)
+	}
+	if m.total != nil {
+		fields = append(fields, batchmsg.FieldTotal)
+	}
+	if m.success != nil {
+		fields = append(fields, batchmsg.FieldSuccess)
+	}
+	if m.fail != nil {
+		fields = append(fields, batchmsg.FieldFail)
+	}
+	if m.start_time != nil {
+		fields = append(fields, batchmsg.FieldStartTime)
+	}
+	if m.stop_time != nil {
+		fields = append(fields, batchmsg.FieldStopTime)
+	}
+	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 *BatchMsgMutation) Field(name string) (ent.Value, bool) {
+	switch name {
+	case batchmsg.FieldCreatedAt:
+		return m.CreatedAt()
+	case batchmsg.FieldUpdatedAt:
+		return m.UpdatedAt()
+	case batchmsg.FieldDeletedAt:
+		return m.DeletedAt()
+	case batchmsg.FieldStatus:
+		return m.Status()
+	case batchmsg.FieldBatchNo:
+		return m.BatchNo()
+	case batchmsg.FieldFromwxid:
+		return m.Fromwxid()
+	case batchmsg.FieldMsg:
+		return m.Msg()
+	case batchmsg.FieldTag:
+		return m.Tag()
+	case batchmsg.FieldTotal:
+		return m.Total()
+	case batchmsg.FieldSuccess:
+		return m.Success()
+	case batchmsg.FieldFail:
+		return m.Fail()
+	case batchmsg.FieldStartTime:
+		return m.StartTime()
+	case batchmsg.FieldStopTime:
+		return m.StopTime()
+	}
+	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 *BatchMsgMutation) OldField(ctx context.Context, name string) (ent.Value, error) {
+	switch name {
+	case batchmsg.FieldCreatedAt:
+		return m.OldCreatedAt(ctx)
+	case batchmsg.FieldUpdatedAt:
+		return m.OldUpdatedAt(ctx)
+	case batchmsg.FieldDeletedAt:
+		return m.OldDeletedAt(ctx)
+	case batchmsg.FieldStatus:
+		return m.OldStatus(ctx)
+	case batchmsg.FieldBatchNo:
+		return m.OldBatchNo(ctx)
+	case batchmsg.FieldFromwxid:
+		return m.OldFromwxid(ctx)
+	case batchmsg.FieldMsg:
+		return m.OldMsg(ctx)
+	case batchmsg.FieldTag:
+		return m.OldTag(ctx)
+	case batchmsg.FieldTotal:
+		return m.OldTotal(ctx)
+	case batchmsg.FieldSuccess:
+		return m.OldSuccess(ctx)
+	case batchmsg.FieldFail:
+		return m.OldFail(ctx)
+	case batchmsg.FieldStartTime:
+		return m.OldStartTime(ctx)
+	case batchmsg.FieldStopTime:
+		return m.OldStopTime(ctx)
+	}
+	return nil, fmt.Errorf("unknown BatchMsg 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 *BatchMsgMutation) SetField(name string, value ent.Value) error {
+	switch name {
+	case batchmsg.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 batchmsg.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 batchmsg.FieldDeletedAt:
+		v, ok := value.(time.Time)
+		if !ok {
+			return fmt.Errorf("unexpected type %T for field %s", value, name)
+		}
+		m.SetDeletedAt(v)
+		return nil
+	case batchmsg.FieldStatus:
+		v, ok := value.(uint8)
+		if !ok {
+			return fmt.Errorf("unexpected type %T for field %s", value, name)
+		}
+		m.SetStatus(v)
+		return nil
+	case batchmsg.FieldBatchNo:
+		v, ok := value.(string)
+		if !ok {
+			return fmt.Errorf("unexpected type %T for field %s", value, name)
+		}
+		m.SetBatchNo(v)
+		return nil
+	case batchmsg.FieldFromwxid:
+		v, ok := value.(string)
+		if !ok {
+			return fmt.Errorf("unexpected type %T for field %s", value, name)
+		}
+		m.SetFromwxid(v)
+		return nil
+	case batchmsg.FieldMsg:
+		v, ok := value.(string)
+		if !ok {
+			return fmt.Errorf("unexpected type %T for field %s", value, name)
+		}
+		m.SetMsg(v)
+		return nil
+	case batchmsg.FieldTag:
+		v, ok := value.(string)
+		if !ok {
+			return fmt.Errorf("unexpected type %T for field %s", value, name)
+		}
+		m.SetTag(v)
+		return nil
+	case batchmsg.FieldTotal:
+		v, ok := value.(int32)
+		if !ok {
+			return fmt.Errorf("unexpected type %T for field %s", value, name)
+		}
+		m.SetTotal(v)
+		return nil
+	case batchmsg.FieldSuccess:
+		v, ok := value.(int32)
+		if !ok {
+			return fmt.Errorf("unexpected type %T for field %s", value, name)
+		}
+		m.SetSuccess(v)
+		return nil
+	case batchmsg.FieldFail:
+		v, ok := value.(int32)
+		if !ok {
+			return fmt.Errorf("unexpected type %T for field %s", value, name)
+		}
+		m.SetFail(v)
+		return nil
+	case batchmsg.FieldStartTime:
+		v, ok := value.(time.Time)
+		if !ok {
+			return fmt.Errorf("unexpected type %T for field %s", value, name)
+		}
+		m.SetStartTime(v)
+		return nil
+	case batchmsg.FieldStopTime:
+		v, ok := value.(time.Time)
+		if !ok {
+			return fmt.Errorf("unexpected type %T for field %s", value, name)
+		}
+		m.SetStopTime(v)
+		return nil
+	}
+	return fmt.Errorf("unknown BatchMsg field %s", name)
+}
+
+// AddedFields returns all numeric fields that were incremented/decremented during
+// this mutation.
+func (m *BatchMsgMutation) AddedFields() []string {
+	var fields []string
+	if m.addstatus != nil {
+		fields = append(fields, batchmsg.FieldStatus)
+	}
+	if m.addtotal != nil {
+		fields = append(fields, batchmsg.FieldTotal)
+	}
+	if m.addsuccess != nil {
+		fields = append(fields, batchmsg.FieldSuccess)
+	}
+	if m.addfail != nil {
+		fields = append(fields, batchmsg.FieldFail)
+	}
+	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 *BatchMsgMutation) AddedField(name string) (ent.Value, bool) {
+	switch name {
+	case batchmsg.FieldStatus:
+		return m.AddedStatus()
+	case batchmsg.FieldTotal:
+		return m.AddedTotal()
+	case batchmsg.FieldSuccess:
+		return m.AddedSuccess()
+	case batchmsg.FieldFail:
+		return m.AddedFail()
+	}
+	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 *BatchMsgMutation) AddField(name string, value ent.Value) error {
+	switch name {
+	case batchmsg.FieldStatus:
+		v, ok := value.(int8)
+		if !ok {
+			return fmt.Errorf("unexpected type %T for field %s", value, name)
+		}
+		m.AddStatus(v)
+		return nil
+	case batchmsg.FieldTotal:
+		v, ok := value.(int32)
+		if !ok {
+			return fmt.Errorf("unexpected type %T for field %s", value, name)
+		}
+		m.AddTotal(v)
+		return nil
+	case batchmsg.FieldSuccess:
+		v, ok := value.(int32)
+		if !ok {
+			return fmt.Errorf("unexpected type %T for field %s", value, name)
+		}
+		m.AddSuccess(v)
+		return nil
+	case batchmsg.FieldFail:
+		v, ok := value.(int32)
+		if !ok {
+			return fmt.Errorf("unexpected type %T for field %s", value, name)
+		}
+		m.AddFail(v)
+		return nil
+	}
+	return fmt.Errorf("unknown BatchMsg numeric field %s", name)
+}
+
+// ClearedFields returns all nullable fields that were cleared during this
+// mutation.
+func (m *BatchMsgMutation) ClearedFields() []string {
+	var fields []string
+	if m.FieldCleared(batchmsg.FieldDeletedAt) {
+		fields = append(fields, batchmsg.FieldDeletedAt)
+	}
+	if m.FieldCleared(batchmsg.FieldStatus) {
+		fields = append(fields, batchmsg.FieldStatus)
+	}
+	if m.FieldCleared(batchmsg.FieldBatchNo) {
+		fields = append(fields, batchmsg.FieldBatchNo)
+	}
+	if m.FieldCleared(batchmsg.FieldFromwxid) {
+		fields = append(fields, batchmsg.FieldFromwxid)
+	}
+	if m.FieldCleared(batchmsg.FieldMsg) {
+		fields = append(fields, batchmsg.FieldMsg)
+	}
+	if m.FieldCleared(batchmsg.FieldTag) {
+		fields = append(fields, batchmsg.FieldTag)
+	}
+	if m.FieldCleared(batchmsg.FieldTotal) {
+		fields = append(fields, batchmsg.FieldTotal)
+	}
+	if m.FieldCleared(batchmsg.FieldSuccess) {
+		fields = append(fields, batchmsg.FieldSuccess)
+	}
+	if m.FieldCleared(batchmsg.FieldFail) {
+		fields = append(fields, batchmsg.FieldFail)
+	}
+	if m.FieldCleared(batchmsg.FieldStartTime) {
+		fields = append(fields, batchmsg.FieldStartTime)
+	}
+	if m.FieldCleared(batchmsg.FieldStopTime) {
+		fields = append(fields, batchmsg.FieldStopTime)
+	}
+	return fields
+}
+
+// FieldCleared returns a boolean indicating if a field with the given name was
+// cleared in this mutation.
+func (m *BatchMsgMutation) 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 *BatchMsgMutation) ClearField(name string) error {
+	switch name {
+	case batchmsg.FieldDeletedAt:
+		m.ClearDeletedAt()
+		return nil
+	case batchmsg.FieldStatus:
+		m.ClearStatus()
+		return nil
+	case batchmsg.FieldBatchNo:
+		m.ClearBatchNo()
+		return nil
+	case batchmsg.FieldFromwxid:
+		m.ClearFromwxid()
+		return nil
+	case batchmsg.FieldMsg:
+		m.ClearMsg()
+		return nil
+	case batchmsg.FieldTag:
+		m.ClearTag()
+		return nil
+	case batchmsg.FieldTotal:
+		m.ClearTotal()
+		return nil
+	case batchmsg.FieldSuccess:
+		m.ClearSuccess()
+		return nil
+	case batchmsg.FieldFail:
+		m.ClearFail()
+		return nil
+	case batchmsg.FieldStartTime:
+		m.ClearStartTime()
+		return nil
+	case batchmsg.FieldStopTime:
+		m.ClearStopTime()
+		return nil
+	}
+	return fmt.Errorf("unknown BatchMsg 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 *BatchMsgMutation) ResetField(name string) error {
+	switch name {
+	case batchmsg.FieldCreatedAt:
+		m.ResetCreatedAt()
+		return nil
+	case batchmsg.FieldUpdatedAt:
+		m.ResetUpdatedAt()
+		return nil
+	case batchmsg.FieldDeletedAt:
+		m.ResetDeletedAt()
+		return nil
+	case batchmsg.FieldStatus:
+		m.ResetStatus()
+		return nil
+	case batchmsg.FieldBatchNo:
+		m.ResetBatchNo()
+		return nil
+	case batchmsg.FieldFromwxid:
+		m.ResetFromwxid()
+		return nil
+	case batchmsg.FieldMsg:
+		m.ResetMsg()
+		return nil
+	case batchmsg.FieldTag:
+		m.ResetTag()
+		return nil
+	case batchmsg.FieldTotal:
+		m.ResetTotal()
+		return nil
+	case batchmsg.FieldSuccess:
+		m.ResetSuccess()
+		return nil
+	case batchmsg.FieldFail:
+		m.ResetFail()
+		return nil
+	case batchmsg.FieldStartTime:
+		m.ResetStartTime()
+		return nil
+	case batchmsg.FieldStopTime:
+		m.ResetStopTime()
+		return nil
+	}
+	return fmt.Errorf("unknown BatchMsg field %s", name)
+}
+
+// AddedEdges returns all edge names that were set/added in this mutation.
+func (m *BatchMsgMutation) 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 *BatchMsgMutation) AddedIDs(name string) []ent.Value {
+	return nil
+}
+
+// RemovedEdges returns all edge names that were removed in this mutation.
+func (m *BatchMsgMutation) 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 *BatchMsgMutation) RemovedIDs(name string) []ent.Value {
+	return nil
+}
+
+// ClearedEdges returns all edge names that were cleared in this mutation.
+func (m *BatchMsgMutation) 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 *BatchMsgMutation) 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 *BatchMsgMutation) ClearEdge(name string) error {
+	return fmt.Errorf("unknown BatchMsg 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 *BatchMsgMutation) ResetEdge(name string) error {
+	return fmt.Errorf("unknown BatchMsg edge %s", name)
+}
+
 // ContactMutation represents an operation that mutates the Contact nodes in the graph.
 type ContactMutation struct {
 	config

+ 82 - 0
ent/pagination.go

@@ -5,6 +5,7 @@ package ent
 import (
 	"context"
 	"fmt"
+	"wechat-api/ent/batchmsg"
 	"wechat-api/ent/contact"
 	"wechat-api/ent/label"
 	"wechat-api/ent/labelrelationship"
@@ -63,6 +64,87 @@ func (o OrderDirection) reverse() OrderDirection {
 
 const errInvalidPagination = "INVALID_PAGINATION"
 
+type BatchMsgPager struct {
+	Order  batchmsg.OrderOption
+	Filter func(*BatchMsgQuery) (*BatchMsgQuery, error)
+}
+
+// BatchMsgPaginateOption enables pagination customization.
+type BatchMsgPaginateOption func(*BatchMsgPager)
+
+// DefaultBatchMsgOrder is the default ordering of BatchMsg.
+var DefaultBatchMsgOrder = Desc(batchmsg.FieldID)
+
+func newBatchMsgPager(opts []BatchMsgPaginateOption) (*BatchMsgPager, error) {
+	pager := &BatchMsgPager{}
+	for _, opt := range opts {
+		opt(pager)
+	}
+	if pager.Order == nil {
+		pager.Order = DefaultBatchMsgOrder
+	}
+	return pager, nil
+}
+
+func (p *BatchMsgPager) ApplyFilter(query *BatchMsgQuery) (*BatchMsgQuery, error) {
+	if p.Filter != nil {
+		return p.Filter(query)
+	}
+	return query, nil
+}
+
+// BatchMsgPageList is BatchMsg PageList result.
+type BatchMsgPageList struct {
+	List        []*BatchMsg  `json:"list"`
+	PageDetails *PageDetails `json:"pageDetails"`
+}
+
+func (bm *BatchMsgQuery) Page(
+	ctx context.Context, pageNum uint64, pageSize uint64, opts ...BatchMsgPaginateOption,
+) (*BatchMsgPageList, error) {
+
+	pager, err := newBatchMsgPager(opts)
+	if err != nil {
+		return nil, err
+	}
+
+	if bm, err = pager.ApplyFilter(bm); err != nil {
+		return nil, err
+	}
+
+	ret := &BatchMsgPageList{}
+
+	ret.PageDetails = &PageDetails{
+		Page: pageNum,
+		Size: pageSize,
+	}
+
+	query := bm.Clone()
+	query.ctx.Fields = nil
+	count, err := query.Count(ctx)
+
+	if err != nil {
+		return nil, err
+	}
+
+	ret.PageDetails.Total = uint64(count)
+
+	if pager.Order != nil {
+		bm = bm.Order(pager.Order)
+	} else {
+		bm = bm.Order(DefaultBatchMsgOrder)
+	}
+
+	bm = bm.Offset(int((pageNum - 1) * pageSize)).Limit(int(pageSize))
+	list, err := bm.All(ctx)
+	if err != nil {
+		return nil, err
+	}
+	ret.List = list
+
+	return ret, nil
+}
+
 type ContactPager struct {
 	Order  contact.OrderOption
 	Filter func(*ContactQuery) (*ContactQuery, error)

+ 3 - 0
ent/predicate/predicate.go

@@ -6,6 +6,9 @@ import (
 	"entgo.io/ent/dialect/sql"
 )
 
+// BatchMsg is the predicate function for batchmsg builders.
+type BatchMsg func(*sql.Selector)
+
 // Contact is the predicate function for contact builders.
 type Contact func(*sql.Selector)
 

+ 20 - 0
ent/runtime/runtime.go

@@ -4,6 +4,7 @@ package runtime
 
 import (
 	"time"
+	"wechat-api/ent/batchmsg"
 	"wechat-api/ent/contact"
 	"wechat-api/ent/label"
 	"wechat-api/ent/labelrelationship"
@@ -21,6 +22,25 @@ import (
 // (default values, validators, hooks and policies) and stitches it
 // to their package variables.
 func init() {
+	batchmsgMixin := schema.BatchMsg{}.Mixin()
+	batchmsgMixinHooks1 := batchmsgMixin[1].Hooks()
+	batchmsg.Hooks[0] = batchmsgMixinHooks1[0]
+	batchmsgMixinInters1 := batchmsgMixin[1].Interceptors()
+	batchmsg.Interceptors[0] = batchmsgMixinInters1[0]
+	batchmsgMixinFields0 := batchmsgMixin[0].Fields()
+	_ = batchmsgMixinFields0
+	batchmsgFields := schema.BatchMsg{}.Fields()
+	_ = batchmsgFields
+	// batchmsgDescCreatedAt is the schema descriptor for created_at field.
+	batchmsgDescCreatedAt := batchmsgMixinFields0[1].Descriptor()
+	// batchmsg.DefaultCreatedAt holds the default value on creation for the created_at field.
+	batchmsg.DefaultCreatedAt = batchmsgDescCreatedAt.Default.(func() time.Time)
+	// batchmsgDescUpdatedAt is the schema descriptor for updated_at field.
+	batchmsgDescUpdatedAt := batchmsgMixinFields0[2].Descriptor()
+	// batchmsg.DefaultUpdatedAt holds the default value on creation for the updated_at field.
+	batchmsg.DefaultUpdatedAt = batchmsgDescUpdatedAt.Default.(func() time.Time)
+	// batchmsg.UpdateDefaultUpdatedAt holds the default value on update for the updated_at field.
+	batchmsg.UpdateDefaultUpdatedAt = batchmsgDescUpdatedAt.UpdateDefault.(func() time.Time)
 	contactMixin := schema.Contact{}.Mixin()
 	contactMixinHooks2 := contactMixin[2].Hooks()
 	contact.Hooks[0] = contactMixinHooks2[0]

+ 51 - 0
ent/schema/batch_msg.go

@@ -0,0 +1,51 @@
+package schema
+
+import (
+	"wechat-api/ent/schema/localmixin"
+
+	"entgo.io/ent"
+	"entgo.io/ent/dialect/entsql"
+	"entgo.io/ent/schema"
+	"entgo.io/ent/schema/field"
+	"entgo.io/ent/schema/index"
+	"github.com/suyuan32/simple-admin-common/orm/ent/mixins"
+)
+
+type BatchMsg struct {
+	ent.Schema
+}
+
+func (BatchMsg) Fields() []ent.Field {
+	return []ent.Field{
+		field.Uint8("status").Optional().Comment("状态 0 未开始 1 开始发送 2 发送完成 3 发送中止"),
+		field.String("batch_no").Optional().Unique().Comment("批次号"),
+		field.String("fromwxid").Optional().Comment("发送方微信ID"),
+		field.String("msg").Optional().Comment("内容"),
+		field.String("tag").Optional().Comment("发送规则 all 全部 tag1,tag2 按tag发送"),
+		field.Int32("total").Optional().Comment("总数"),
+		field.Int32("success").Optional().Comment("成功数量"),
+		field.Int32("fail").Optional().Comment("失败数量"),
+		field.Time("start_time").Optional().Comment("开始时间"),
+		field.Time("stop_time").Optional().Comment("结束时间")}
+}
+func (BatchMsg) Mixin() []ent.Mixin {
+	return []ent.Mixin{
+		mixins.IDMixin{},
+		localmixin.SoftDeleteMixin{},
+	}
+}
+func (BatchMsg) Edges() []ent.Edge {
+	return nil
+}
+
+func (BatchMsg) Indexes() []ent.Index {
+	return []ent.Index{
+		index.Fields("batch_no").Unique()}
+}
+
+func (BatchMsg) Annotations() []schema.Annotation {
+	return []schema.Annotation{
+		entsql.WithComments(true),
+		entsql.Annotation{Table: "batch_msgs"},
+	}
+}

+ 7 - 2
ent/schema/contact.go

@@ -1,6 +1,8 @@
 package schema
 
 import (
+	"wechat-api/ent/schema/localmixin"
+
 	"entgo.io/ent"
 	"entgo.io/ent/dialect/entsql"
 	"entgo.io/ent/schema"
@@ -8,7 +10,6 @@ import (
 	"entgo.io/ent/schema/field"
 	"entgo.io/ent/schema/index"
 	"github.com/suyuan32/simple-admin-common/orm/ent/mixins"
-	"wechat-api/ent/schema/localmixin"
 )
 
 type Contact struct {
@@ -88,6 +89,10 @@ func (Contact) Edges() []ent.Edge {
 		edge.To("contact_messages", MessageRecords.Type),
 	}
 }
+
 func (Contact) Annotations() []schema.Annotation {
-	return []schema.Annotation{entsql.Annotation{Table: "contact"}}
+	return []schema.Annotation{
+		entsql.WithComments(true),
+		entsql.Annotation{Table: "contacts"},
+	}
 }

+ 7 - 2
ent/schema/label.go

@@ -1,6 +1,8 @@
 package schema
 
 import (
+	"wechat-api/ent/schema/localmixin"
+
 	"entgo.io/ent"
 	"entgo.io/ent/dialect/entsql"
 	"entgo.io/ent/schema"
@@ -8,7 +10,6 @@ import (
 	"entgo.io/ent/schema/field"
 	"entgo.io/ent/schema/index"
 	"github.com/suyuan32/simple-admin-common/orm/ent/mixins"
-	"wechat-api/ent/schema/localmixin"
 )
 
 type Label struct {
@@ -54,6 +55,10 @@ func (Label) Edges() []ent.Edge {
 		edge.To("label_relationships", LabelRelationship.Type),
 	}
 }
+
 func (Label) Annotations() []schema.Annotation {
-	return []schema.Annotation{entsql.Annotation{Table: "label"}}
+	return []schema.Annotation{
+		entsql.WithComments(true),
+		entsql.Annotation{Table: "labels"},
+	}
 }

+ 7 - 2
ent/schema/label_relationship.go

@@ -1,6 +1,8 @@
 package schema
 
 import (
+	"wechat-api/ent/schema/localmixin"
+
 	"entgo.io/ent"
 	"entgo.io/ent/dialect/entsql"
 	"entgo.io/ent/schema"
@@ -8,7 +10,6 @@ import (
 	"entgo.io/ent/schema/field"
 	"entgo.io/ent/schema/index"
 	"github.com/suyuan32/simple-admin-common/orm/ent/mixins"
-	"wechat-api/ent/schema/localmixin"
 )
 
 type LabelRelationship struct {
@@ -55,6 +56,10 @@ func (LabelRelationship) Edges() []ent.Edge {
 			Required(),
 	}
 }
+
 func (LabelRelationship) Annotations() []schema.Annotation {
-	return []schema.Annotation{entsql.Annotation{Table: "label_relationship"}}
+	return []schema.Annotation{
+		entsql.WithComments(true),
+		entsql.Annotation{Table: "label_relationships"},
+	}
 }

+ 5 - 1
ent/schema/message.go

@@ -31,6 +31,10 @@ func (Message) Fields() []ent.Field {
 func (Message) Edges() []ent.Edge {
 	return nil
 }
+
 func (Message) Annotations() []schema.Annotation {
-	return []schema.Annotation{entsql.Annotation{Table: "message"}}
+	return []schema.Annotation{
+		entsql.WithComments(true),
+		entsql.Annotation{Table: "messages"},
+	}
 }

+ 7 - 3
ent/schema/message_records.go

@@ -1,6 +1,9 @@
 package schema
 
 import (
+	"wechat-api/ent/custom_types"
+	"wechat-api/ent/schema/localmixin"
+
 	"entgo.io/ent"
 	"entgo.io/ent/dialect/entsql"
 	"entgo.io/ent/schema"
@@ -8,8 +11,6 @@ import (
 	"entgo.io/ent/schema/field"
 	"entgo.io/ent/schema/index"
 	"github.com/suyuan32/simple-admin-common/orm/ent/mixins"
-	"wechat-api/ent/custom_types"
-	"wechat-api/ent/schema/localmixin"
 )
 
 type MessageRecords struct {
@@ -89,5 +90,8 @@ func (MessageRecords) Edges() []ent.Edge {
 }
 
 func (MessageRecords) Annotations() []schema.Annotation {
-	return []schema.Annotation{entsql.Annotation{Table: "message_records"}}
+	return []schema.Annotation{
+		entsql.WithComments(true),
+		entsql.Annotation{Table: "message_recordss"},
+	}
 }

+ 5 - 1
ent/schema/server.go

@@ -53,6 +53,10 @@ func (Server) Edges() []ent.Edge {
 		edge.To("wxs", Wx.Type),
 	}
 }
+
 func (Server) Annotations() []schema.Annotation {
-	return []schema.Annotation{entsql.Annotation{Table: "server"}}
+	return []schema.Annotation{
+		entsql.WithComments(true),
+		entsql.Annotation{Table: "servers"},
+	}
 }

+ 7 - 3
ent/schema/sop_node.go

@@ -1,6 +1,9 @@
 package schema
 
 import (
+	"wechat-api/ent/custom_types"
+	"wechat-api/ent/schema/localmixin"
+
 	"entgo.io/ent"
 	"entgo.io/ent/dialect/entsql"
 	"entgo.io/ent/schema"
@@ -8,8 +11,6 @@ import (
 	"entgo.io/ent/schema/field"
 	"entgo.io/ent/schema/index"
 	"github.com/suyuan32/simple-admin-common/orm/ent/mixins"
-	"wechat-api/ent/custom_types"
-	"wechat-api/ent/schema/localmixin"
 )
 
 type SopNode struct {
@@ -71,5 +72,8 @@ func (SopNode) Edges() []ent.Edge {
 }
 
 func (SopNode) Annotations() []schema.Annotation {
-	return []schema.Annotation{entsql.Annotation{Table: "sop_node"}}
+	return []schema.Annotation{
+		entsql.WithComments(true),
+		entsql.Annotation{Table: "sop_nodes"},
+	}
 }

+ 8 - 3
ent/schema/sop_stage.go

@@ -1,6 +1,9 @@
 package schema
 
 import (
+	"wechat-api/ent/custom_types"
+	"wechat-api/ent/schema/localmixin"
+
 	"entgo.io/ent"
 	"entgo.io/ent/dialect/entsql"
 	"entgo.io/ent/schema"
@@ -8,8 +11,6 @@ import (
 	"entgo.io/ent/schema/field"
 	"entgo.io/ent/schema/index"
 	"github.com/suyuan32/simple-admin-common/orm/ent/mixins"
-	"wechat-api/ent/custom_types"
-	"wechat-api/ent/schema/localmixin"
 )
 
 type SopStage struct {
@@ -70,6 +71,10 @@ func (SopStage) Edges() []ent.Edge {
 		edge.To("stage_messages", MessageRecords.Type),
 	}
 }
+
 func (SopStage) Annotations() []schema.Annotation {
-	return []schema.Annotation{entsql.Annotation{Table: "sop_stage"}}
+	return []schema.Annotation{
+		entsql.WithComments(true),
+		entsql.Annotation{Table: "sop_stages"},
+	}
 }

+ 6 - 2
ent/schema/sop_task.go

@@ -1,6 +1,8 @@
 package schema
 
 import (
+	"wechat-api/ent/schema/localmixin"
+
 	"entgo.io/ent"
 	"entgo.io/ent/dialect/entsql"
 	"entgo.io/ent/schema"
@@ -8,7 +10,6 @@ import (
 	"entgo.io/ent/schema/field"
 	"entgo.io/ent/schema/index"
 	"github.com/suyuan32/simple-admin-common/orm/ent/mixins"
-	"wechat-api/ent/schema/localmixin"
 )
 
 type SopTask struct {
@@ -59,5 +60,8 @@ func (SopTask) Edges() []ent.Edge {
 }
 
 func (SopTask) Annotations() []schema.Annotation {
-	return []schema.Annotation{entsql.Annotation{Table: "sop_task"}}
+	return []schema.Annotation{
+		entsql.WithComments(true),
+		entsql.Annotation{Table: "sop_tasks"},
+	}
 }

+ 5 - 1
ent/schema/wx.go

@@ -72,6 +72,10 @@ func (Wx) Edges() []ent.Edge {
 		edge.From("server", Server.Type).Ref("wxs").Unique().Field("server_id"),
 	}
 }
+
 func (Wx) Annotations() []schema.Annotation {
-	return []schema.Annotation{entsql.Annotation{Table: "wx"}}
+	return []schema.Annotation{
+		entsql.WithComments(true),
+		entsql.Annotation{Table: "wxs"},
+	}
 }

+ 3 - 3
ent/server/server.go

@@ -34,12 +34,12 @@ const (
 	// EdgeWxs holds the string denoting the wxs edge name in mutations.
 	EdgeWxs = "wxs"
 	// Table holds the table name of the server in the database.
-	Table = "server"
+	Table = "servers"
 	// WxsTable is the table that holds the wxs relation/edge.
-	WxsTable = "wx"
+	WxsTable = "wxs"
 	// WxsInverseTable is the table name for the Wx entity.
 	// It exists in this package in order to avoid circular dependency with the "wx" package.
-	WxsInverseTable = "wx"
+	WxsInverseTable = "wxs"
 	// WxsColumn is the table column denoting the wxs relation/edge.
 	WxsColumn = "server_id"
 )

+ 288 - 0
ent/set_not_nil.go

@@ -8,6 +8,294 @@ import (
 )
 
 // set field if value's pointer is not nil.
+func (bm *BatchMsgUpdate) SetNotNilUpdatedAt(value *time.Time) *BatchMsgUpdate {
+	if value != nil {
+		return bm.SetUpdatedAt(*value)
+	}
+	return bm
+}
+
+// set field if value's pointer is not nil.
+func (bm *BatchMsgUpdateOne) SetNotNilUpdatedAt(value *time.Time) *BatchMsgUpdateOne {
+	if value != nil {
+		return bm.SetUpdatedAt(*value)
+	}
+	return bm
+}
+
+// set field if value's pointer is not nil.
+func (bm *BatchMsgCreate) SetNotNilUpdatedAt(value *time.Time) *BatchMsgCreate {
+	if value != nil {
+		return bm.SetUpdatedAt(*value)
+	}
+	return bm
+}
+
+// set field if value's pointer is not nil.
+func (bm *BatchMsgUpdate) SetNotNilDeletedAt(value *time.Time) *BatchMsgUpdate {
+	if value != nil {
+		return bm.SetDeletedAt(*value)
+	}
+	return bm
+}
+
+// set field if value's pointer is not nil.
+func (bm *BatchMsgUpdateOne) SetNotNilDeletedAt(value *time.Time) *BatchMsgUpdateOne {
+	if value != nil {
+		return bm.SetDeletedAt(*value)
+	}
+	return bm
+}
+
+// set field if value's pointer is not nil.
+func (bm *BatchMsgCreate) SetNotNilDeletedAt(value *time.Time) *BatchMsgCreate {
+	if value != nil {
+		return bm.SetDeletedAt(*value)
+	}
+	return bm
+}
+
+// set field if value's pointer is not nil.
+func (bm *BatchMsgUpdate) SetNotNilStatus(value *uint8) *BatchMsgUpdate {
+	if value != nil {
+		return bm.SetStatus(*value)
+	}
+	return bm
+}
+
+// set field if value's pointer is not nil.
+func (bm *BatchMsgUpdateOne) SetNotNilStatus(value *uint8) *BatchMsgUpdateOne {
+	if value != nil {
+		return bm.SetStatus(*value)
+	}
+	return bm
+}
+
+// set field if value's pointer is not nil.
+func (bm *BatchMsgCreate) SetNotNilStatus(value *uint8) *BatchMsgCreate {
+	if value != nil {
+		return bm.SetStatus(*value)
+	}
+	return bm
+}
+
+// set field if value's pointer is not nil.
+func (bm *BatchMsgUpdate) SetNotNilBatchNo(value *string) *BatchMsgUpdate {
+	if value != nil {
+		return bm.SetBatchNo(*value)
+	}
+	return bm
+}
+
+// set field if value's pointer is not nil.
+func (bm *BatchMsgUpdateOne) SetNotNilBatchNo(value *string) *BatchMsgUpdateOne {
+	if value != nil {
+		return bm.SetBatchNo(*value)
+	}
+	return bm
+}
+
+// set field if value's pointer is not nil.
+func (bm *BatchMsgCreate) SetNotNilBatchNo(value *string) *BatchMsgCreate {
+	if value != nil {
+		return bm.SetBatchNo(*value)
+	}
+	return bm
+}
+
+// set field if value's pointer is not nil.
+func (bm *BatchMsgUpdate) SetNotNilFromwxid(value *string) *BatchMsgUpdate {
+	if value != nil {
+		return bm.SetFromwxid(*value)
+	}
+	return bm
+}
+
+// set field if value's pointer is not nil.
+func (bm *BatchMsgUpdateOne) SetNotNilFromwxid(value *string) *BatchMsgUpdateOne {
+	if value != nil {
+		return bm.SetFromwxid(*value)
+	}
+	return bm
+}
+
+// set field if value's pointer is not nil.
+func (bm *BatchMsgCreate) SetNotNilFromwxid(value *string) *BatchMsgCreate {
+	if value != nil {
+		return bm.SetFromwxid(*value)
+	}
+	return bm
+}
+
+// set field if value's pointer is not nil.
+func (bm *BatchMsgUpdate) SetNotNilMsg(value *string) *BatchMsgUpdate {
+	if value != nil {
+		return bm.SetMsg(*value)
+	}
+	return bm
+}
+
+// set field if value's pointer is not nil.
+func (bm *BatchMsgUpdateOne) SetNotNilMsg(value *string) *BatchMsgUpdateOne {
+	if value != nil {
+		return bm.SetMsg(*value)
+	}
+	return bm
+}
+
+// set field if value's pointer is not nil.
+func (bm *BatchMsgCreate) SetNotNilMsg(value *string) *BatchMsgCreate {
+	if value != nil {
+		return bm.SetMsg(*value)
+	}
+	return bm
+}
+
+// set field if value's pointer is not nil.
+func (bm *BatchMsgUpdate) SetNotNilTag(value *string) *BatchMsgUpdate {
+	if value != nil {
+		return bm.SetTag(*value)
+	}
+	return bm
+}
+
+// set field if value's pointer is not nil.
+func (bm *BatchMsgUpdateOne) SetNotNilTag(value *string) *BatchMsgUpdateOne {
+	if value != nil {
+		return bm.SetTag(*value)
+	}
+	return bm
+}
+
+// set field if value's pointer is not nil.
+func (bm *BatchMsgCreate) SetNotNilTag(value *string) *BatchMsgCreate {
+	if value != nil {
+		return bm.SetTag(*value)
+	}
+	return bm
+}
+
+// set field if value's pointer is not nil.
+func (bm *BatchMsgUpdate) SetNotNilTotal(value *int32) *BatchMsgUpdate {
+	if value != nil {
+		return bm.SetTotal(*value)
+	}
+	return bm
+}
+
+// set field if value's pointer is not nil.
+func (bm *BatchMsgUpdateOne) SetNotNilTotal(value *int32) *BatchMsgUpdateOne {
+	if value != nil {
+		return bm.SetTotal(*value)
+	}
+	return bm
+}
+
+// set field if value's pointer is not nil.
+func (bm *BatchMsgCreate) SetNotNilTotal(value *int32) *BatchMsgCreate {
+	if value != nil {
+		return bm.SetTotal(*value)
+	}
+	return bm
+}
+
+// set field if value's pointer is not nil.
+func (bm *BatchMsgUpdate) SetNotNilSuccess(value *int32) *BatchMsgUpdate {
+	if value != nil {
+		return bm.SetSuccess(*value)
+	}
+	return bm
+}
+
+// set field if value's pointer is not nil.
+func (bm *BatchMsgUpdateOne) SetNotNilSuccess(value *int32) *BatchMsgUpdateOne {
+	if value != nil {
+		return bm.SetSuccess(*value)
+	}
+	return bm
+}
+
+// set field if value's pointer is not nil.
+func (bm *BatchMsgCreate) SetNotNilSuccess(value *int32) *BatchMsgCreate {
+	if value != nil {
+		return bm.SetSuccess(*value)
+	}
+	return bm
+}
+
+// set field if value's pointer is not nil.
+func (bm *BatchMsgUpdate) SetNotNilFail(value *int32) *BatchMsgUpdate {
+	if value != nil {
+		return bm.SetFail(*value)
+	}
+	return bm
+}
+
+// set field if value's pointer is not nil.
+func (bm *BatchMsgUpdateOne) SetNotNilFail(value *int32) *BatchMsgUpdateOne {
+	if value != nil {
+		return bm.SetFail(*value)
+	}
+	return bm
+}
+
+// set field if value's pointer is not nil.
+func (bm *BatchMsgCreate) SetNotNilFail(value *int32) *BatchMsgCreate {
+	if value != nil {
+		return bm.SetFail(*value)
+	}
+	return bm
+}
+
+// set field if value's pointer is not nil.
+func (bm *BatchMsgUpdate) SetNotNilStartTime(value *time.Time) *BatchMsgUpdate {
+	if value != nil {
+		return bm.SetStartTime(*value)
+	}
+	return bm
+}
+
+// set field if value's pointer is not nil.
+func (bm *BatchMsgUpdateOne) SetNotNilStartTime(value *time.Time) *BatchMsgUpdateOne {
+	if value != nil {
+		return bm.SetStartTime(*value)
+	}
+	return bm
+}
+
+// set field if value's pointer is not nil.
+func (bm *BatchMsgCreate) SetNotNilStartTime(value *time.Time) *BatchMsgCreate {
+	if value != nil {
+		return bm.SetStartTime(*value)
+	}
+	return bm
+}
+
+// set field if value's pointer is not nil.
+func (bm *BatchMsgUpdate) SetNotNilStopTime(value *time.Time) *BatchMsgUpdate {
+	if value != nil {
+		return bm.SetStopTime(*value)
+	}
+	return bm
+}
+
+// set field if value's pointer is not nil.
+func (bm *BatchMsgUpdateOne) SetNotNilStopTime(value *time.Time) *BatchMsgUpdateOne {
+	if value != nil {
+		return bm.SetStopTime(*value)
+	}
+	return bm
+}
+
+// set field if value's pointer is not nil.
+func (bm *BatchMsgCreate) SetNotNilStopTime(value *time.Time) *BatchMsgCreate {
+	if value != nil {
+		return bm.SetStopTime(*value)
+	}
+	return bm
+}
+
+// set field if value's pointer is not nil.
 func (c *ContactUpdate) SetNotNilUpdatedAt(value *time.Time) *ContactUpdate {
 	if value != nil {
 		return c.SetUpdatedAt(*value)

+ 5 - 5
ent/sopnode/sopnode.go

@@ -44,19 +44,19 @@ const (
 	// EdgeNodeMessages holds the string denoting the node_messages edge name in mutations.
 	EdgeNodeMessages = "node_messages"
 	// Table holds the table name of the sopnode in the database.
-	Table = "sop_node"
+	Table = "sop_nodes"
 	// SopStageTable is the table that holds the sop_stage relation/edge.
-	SopStageTable = "sop_node"
+	SopStageTable = "sop_nodes"
 	// SopStageInverseTable is the table name for the SopStage entity.
 	// It exists in this package in order to avoid circular dependency with the "sopstage" package.
-	SopStageInverseTable = "sop_stage"
+	SopStageInverseTable = "sop_stages"
 	// SopStageColumn is the table column denoting the sop_stage relation/edge.
 	SopStageColumn = "stage_id"
 	// NodeMessagesTable is the table that holds the node_messages relation/edge.
-	NodeMessagesTable = "message_records"
+	NodeMessagesTable = "message_recordss"
 	// NodeMessagesInverseTable is the table name for the MessageRecords entity.
 	// It exists in this package in order to avoid circular dependency with the "messagerecords" package.
-	NodeMessagesInverseTable = "message_records"
+	NodeMessagesInverseTable = "message_recordss"
 	// NodeMessagesColumn is the table column denoting the node_messages relation/edge.
 	NodeMessagesColumn = "sub_source_id"
 )

+ 7 - 7
ent/sopstage/sopstage.go

@@ -46,26 +46,26 @@ const (
 	// EdgeStageMessages holds the string denoting the stage_messages edge name in mutations.
 	EdgeStageMessages = "stage_messages"
 	// Table holds the table name of the sopstage in the database.
-	Table = "sop_stage"
+	Table = "sop_stages"
 	// SopTaskTable is the table that holds the sop_task relation/edge.
-	SopTaskTable = "sop_stage"
+	SopTaskTable = "sop_stages"
 	// SopTaskInverseTable is the table name for the SopTask entity.
 	// It exists in this package in order to avoid circular dependency with the "soptask" package.
-	SopTaskInverseTable = "sop_task"
+	SopTaskInverseTable = "sop_tasks"
 	// SopTaskColumn is the table column denoting the sop_task relation/edge.
 	SopTaskColumn = "task_id"
 	// StageNodesTable is the table that holds the stage_nodes relation/edge.
-	StageNodesTable = "sop_node"
+	StageNodesTable = "sop_nodes"
 	// StageNodesInverseTable is the table name for the SopNode entity.
 	// It exists in this package in order to avoid circular dependency with the "sopnode" package.
-	StageNodesInverseTable = "sop_node"
+	StageNodesInverseTable = "sop_nodes"
 	// StageNodesColumn is the table column denoting the stage_nodes relation/edge.
 	StageNodesColumn = "stage_id"
 	// StageMessagesTable is the table that holds the stage_messages relation/edge.
-	StageMessagesTable = "message_records"
+	StageMessagesTable = "message_recordss"
 	// StageMessagesInverseTable is the table name for the MessageRecords entity.
 	// It exists in this package in order to avoid circular dependency with the "messagerecords" package.
-	StageMessagesInverseTable = "message_records"
+	StageMessagesInverseTable = "message_recordss"
 	// StageMessagesColumn is the table column denoting the stage_messages relation/edge.
 	StageMessagesColumn = "source_id"
 )

+ 3 - 3
ent/soptask/soptask.go

@@ -38,12 +38,12 @@ const (
 	// EdgeTaskStages holds the string denoting the task_stages edge name in mutations.
 	EdgeTaskStages = "task_stages"
 	// Table holds the table name of the soptask in the database.
-	Table = "sop_task"
+	Table = "sop_tasks"
 	// TaskStagesTable is the table that holds the task_stages relation/edge.
-	TaskStagesTable = "sop_stage"
+	TaskStagesTable = "sop_stages"
 	// TaskStagesInverseTable is the table name for the SopStage entity.
 	// It exists in this package in order to avoid circular dependency with the "sopstage" package.
-	TaskStagesInverseTable = "sop_stage"
+	TaskStagesInverseTable = "sop_stages"
 	// TaskStagesColumn is the table column denoting the task_stages relation/edge.
 	TaskStagesColumn = "task_id"
 )

+ 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
+	// BatchMsg is the client for interacting with the BatchMsg builders.
+	BatchMsg *BatchMsgClient
 	// Contact is the client for interacting with the Contact builders.
 	Contact *ContactClient
 	// Label is the client for interacting with the Label builders.
@@ -165,6 +167,7 @@ func (tx *Tx) Client() *Client {
 }
 
 func (tx *Tx) init() {
+	tx.BatchMsg = NewBatchMsgClient(tx.config)
 	tx.Contact = NewContactClient(tx.config)
 	tx.Label = NewLabelClient(tx.config)
 	tx.LabelRelationship = NewLabelRelationshipClient(tx.config)
@@ -184,7 +187,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: Contact.QueryXXX(), the query will be executed
+// applies a query, for example: BatchMsg.QueryXXX(), the query will be executed
 // through the driver which created this transaction.
 //
 // Note that txDriver is not goroutine safe.

+ 3 - 3
ent/wx/wx.go

@@ -44,12 +44,12 @@ const (
 	// EdgeServer holds the string denoting the server edge name in mutations.
 	EdgeServer = "server"
 	// Table holds the table name of the wx in the database.
-	Table = "wx"
+	Table = "wxs"
 	// ServerTable is the table that holds the server relation/edge.
-	ServerTable = "wx"
+	ServerTable = "wxs"
 	// ServerInverseTable is the table name for the Server entity.
 	// It exists in this package in order to avoid circular dependency with the "server" package.
-	ServerInverseTable = "server"
+	ServerInverseTable = "servers"
 	// ServerColumn is the table column denoting the server relation/edge.
 	ServerColumn = "server_id"
 )

+ 6 - 0
go.sum

@@ -254,6 +254,8 @@ github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/J
 github.com/imroc/req/v3 v3.43.1 h1:tsWAhvxik4egtHAvMlxcjaWJtHlJL8EpBqJMOm5rmyQ=
 github.com/imroc/req/v3 v3.43.1/go.mod h1:SQIz5iYop16MJxbo8ib+4LnostGCok8NQf8ToyQc2xA=
 github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
+github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
+github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
 github.com/jackc/chunkreader v1.0.0/go.mod h1:RT6O25fNZIuasFJRyZ4R/Y2BbhasbmZXF9QQ7T3kePo=
 github.com/jackc/chunkreader/v2 v2.0.0/go.mod h1:odVSm741yZoC3dpHEUXIqA9tQRhFrgOHwnPIn9lDKlk=
 github.com/jackc/chunkreader/v2 v2.0.1 h1:i+RDz65UE+mmpjTfyz0MoVTnzeYxroil2G82ki7MGG8=
@@ -362,6 +364,7 @@ github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Ky
 github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
 github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
 github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
+github.com/mattn/go-runewidth v0.0.9 h1:Lm995f3rfxdpd6TSmuVCHVb/QhupuXlYr8sCI/QdE+0=
 github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=
 github.com/mattn/go-sqlite3 v1.14.6/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU=
 github.com/mattn/go-sqlite3 v1.14.22 h1:2gZY6PC6kBnID23Tichd1K+Z0oS6nE/XwU+Vz/5o4kU=
@@ -392,6 +395,7 @@ github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRW
 github.com/nicksnyder/go-i18n/v2 v2.4.0 h1:3IcvPOAvnCKwNm0TB0dLDTuawWEj+ax/RERNC+diLMM=
 github.com/nicksnyder/go-i18n/v2 v2.4.0/go.mod h1:nxYSZE9M0bf3Y70gPQjN9ha7XNHX7gMc814+6wVyEI4=
 github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U=
+github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N7AbDhec=
 github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY=
 github.com/onsi/ginkgo/v2 v2.17.1 h1:V++EzdbhI4ZV4ev0UTIj0PzhzOcReJFyJaLjtSF55M8=
 github.com/onsi/ginkgo/v2 v2.17.1/go.mod h1:llBI3WDLL9Z6taip6f33H76YcWtJv+7R3HigUjbIBOs=
@@ -470,6 +474,8 @@ github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkU
 github.com/spf13/cast v1.6.0 h1:GEiTHELF+vaR5dhz3VqZfFSzZjYbgeKDpBxQVS4GYJ0=
 github.com/spf13/cast v1.6.0/go.mod h1:ancEpBxwJDODSW/UG4rDrAqiKolqNNh2DX3mk86cAdo=
 github.com/spf13/cobra v1.1.3/go.mod h1:pGADOWyqRD/YMrPZigI/zbliZ2wVD/23d+is3pSWzOo=
+github.com/spf13/cobra v1.7.0 h1:hyqWnYt1ZQShIddO5kBpj3vu05/++x6tJ6dg8EC572I=
+github.com/spf13/cobra v1.7.0/go.mod h1:uLxZILRyS/50WlhOIKD7W6V5bgeIt+4sICxh6uRMrb0=
 github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo=
 github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
 github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=