Parcourir la source

Merge branch 'fixbug/632-bowen-wx-org-change' into debug

* fixbug/632-bowen-wx-org-change:
  fixbug
  fixbug
  增加租、联系人、户机构数据一致性检查
  临时提交
boweniac il y a 10 heures
Parent
commit
a351156723

+ 3 - 1
crontask/sync_wx.go

@@ -3,7 +3,9 @@ package crontask
 import "wechat-api/internal/service/wechat"
 
 func (l *CronTask) syncWx() {
-	wechat.SyncAllWx(l.svcCtx)
+
+	syncWx := wechat.SyncWx{Ctx: l.ctx, DB: l.svcCtx.DB}
+	syncWx.SyncAll()
 	//// 获取微信列表
 	//var result types.WorkPhoneGetWeChatsResp
 	//client := req.C().DevMode()

+ 4 - 0
desc/wechat/wx.api

@@ -227,6 +227,10 @@ service Wechat {
     @handler updateWx
     post /wx/update (WxInfo) returns (BaseMsgResp)
 
+    // Change wx organization | 切换租户
+    @handler changeOrganization
+    post /wx/changeOrganization (WxInfo) returns (BaseMsgResp)
+
     // Update wx information | 更新黑白名单
     @handler updateBlockAndAllowList
     post /wx/updateBlockAndAllowList (UpdateBlockAndAllowListReq) returns (BaseMsgResp)

+ 8 - 4
ent/client.go

@@ -3219,12 +3219,14 @@ func (c *LabelClient) QueryLabelRelationships(l *Label) *LabelRelationshipQuery
 
 // Hooks returns the client hooks.
 func (c *LabelClient) Hooks() []Hook {
-	return c.hooks.Label
+	hooks := c.hooks.Label
+	return append(hooks[:len(hooks):len(hooks)], label.Hooks[:]...)
 }
 
 // Interceptors returns the client interceptors.
 func (c *LabelClient) Interceptors() []Interceptor {
-	return c.inters.Label
+	inters := c.inters.Label
+	return append(inters[:len(inters):len(inters)], label.Interceptors[:]...)
 }
 
 func (c *LabelClient) mutate(ctx context.Context, m *LabelMutation) (Value, error) {
@@ -3517,12 +3519,14 @@ func (c *LabelRelationshipClient) QueryLabels(lr *LabelRelationship) *LabelQuery
 
 // Hooks returns the client hooks.
 func (c *LabelRelationshipClient) Hooks() []Hook {
-	return c.hooks.LabelRelationship
+	hooks := c.hooks.LabelRelationship
+	return append(hooks[:len(hooks):len(hooks)], labelrelationship.Hooks[:]...)
 }
 
 // Interceptors returns the client interceptors.
 func (c *LabelRelationshipClient) Interceptors() []Interceptor {
-	return c.inters.LabelRelationship
+	inters := c.inters.LabelRelationship
+	return append(inters[:len(inters):len(inters)], labelrelationship.Interceptors[:]...)
 }
 
 func (c *LabelRelationshipClient) mutate(ctx context.Context, m *LabelRelationshipMutation) (Value, error) {

+ 12 - 1
ent/label.go

@@ -23,6 +23,8 @@ type Label struct {
 	UpdatedAt time.Time `json:"updated_at,omitempty"`
 	// Status 1: normal 2: ban | 状态 1 正常 2 禁用
 	Status uint8 `json:"status,omitempty"`
+	// Delete Time | 删除日期
+	DeletedAt time.Time `json:"deleted_at,omitempty"`
 	// 标签类型:1好友,2群组,3公众号,4企业微信联系人
 	Type int `json:"type,omitempty"`
 	// 标签名称
@@ -68,7 +70,7 @@ func (*Label) scanValues(columns []string) ([]any, error) {
 			values[i] = new(sql.NullInt64)
 		case label.FieldName, label.FieldConditions:
 			values[i] = new(sql.NullString)
-		case label.FieldCreatedAt, label.FieldUpdatedAt:
+		case label.FieldCreatedAt, label.FieldUpdatedAt, label.FieldDeletedAt:
 			values[i] = new(sql.NullTime)
 		default:
 			values[i] = new(sql.UnknownType)
@@ -109,6 +111,12 @@ func (l *Label) assignValues(columns []string, values []any) error {
 			} else if value.Valid {
 				l.Status = uint8(value.Int64)
 			}
+		case label.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 {
+				l.DeletedAt = value.Time
+			}
 		case label.FieldType:
 			if value, ok := values[i].(*sql.NullInt64); !ok {
 				return fmt.Errorf("unexpected type %T for field type", values[i])
@@ -195,6 +203,9 @@ func (l *Label) String() string {
 	builder.WriteString("status=")
 	builder.WriteString(fmt.Sprintf("%v", l.Status))
 	builder.WriteString(", ")
+	builder.WriteString("deleted_at=")
+	builder.WriteString(l.DeletedAt.Format(time.ANSIC))
+	builder.WriteString(", ")
 	builder.WriteString("type=")
 	builder.WriteString(fmt.Sprintf("%v", l.Type))
 	builder.WriteString(", ")

+ 16 - 0
ent/label/label.go

@@ -5,6 +5,7 @@ package label
 import (
 	"time"
 
+	"entgo.io/ent"
 	"entgo.io/ent/dialect/sql"
 	"entgo.io/ent/dialect/sql/sqlgraph"
 )
@@ -20,6 +21,8 @@ const (
 	FieldUpdatedAt = "updated_at"
 	// FieldStatus holds the string denoting the status field in the database.
 	FieldStatus = "status"
+	// FieldDeletedAt holds the string denoting the deleted_at field in the database.
+	FieldDeletedAt = "deleted_at"
 	// FieldType holds the string denoting the type field in the database.
 	FieldType = "type"
 	// FieldName holds the string denoting the name field in the database.
@@ -51,6 +54,7 @@ var Columns = []string{
 	FieldCreatedAt,
 	FieldUpdatedAt,
 	FieldStatus,
+	FieldDeletedAt,
 	FieldType,
 	FieldName,
 	FieldFrom,
@@ -69,7 +73,14 @@ func ValidColumn(column string) bool {
 	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.
@@ -115,6 +126,11 @@ func ByStatus(opts ...sql.OrderTermOption) OrderOption {
 	return sql.OrderByField(FieldStatus, opts...).ToFunc()
 }
 
+// ByDeletedAt orders the results by the deleted_at field.
+func ByDeletedAt(opts ...sql.OrderTermOption) OrderOption {
+	return sql.OrderByField(FieldDeletedAt, opts...).ToFunc()
+}
+
 // ByType orders the results by the type field.
 func ByType(opts ...sql.OrderTermOption) OrderOption {
 	return sql.OrderByField(FieldType, opts...).ToFunc()

+ 55 - 0
ent/label/where.go

@@ -70,6 +70,11 @@ func Status(v uint8) predicate.Label {
 	return predicate.Label(sql.FieldEQ(FieldStatus, v))
 }
 
+// DeletedAt applies equality check predicate on the "deleted_at" field. It's identical to DeletedAtEQ.
+func DeletedAt(v time.Time) predicate.Label {
+	return predicate.Label(sql.FieldEQ(FieldDeletedAt, v))
+}
+
 // Type applies equality check predicate on the "type" field. It's identical to TypeEQ.
 func Type(v int) predicate.Label {
 	return predicate.Label(sql.FieldEQ(FieldType, v))
@@ -230,6 +235,56 @@ func StatusNotNil() predicate.Label {
 	return predicate.Label(sql.FieldNotNull(FieldStatus))
 }
 
+// DeletedAtEQ applies the EQ predicate on the "deleted_at" field.
+func DeletedAtEQ(v time.Time) predicate.Label {
+	return predicate.Label(sql.FieldEQ(FieldDeletedAt, v))
+}
+
+// DeletedAtNEQ applies the NEQ predicate on the "deleted_at" field.
+func DeletedAtNEQ(v time.Time) predicate.Label {
+	return predicate.Label(sql.FieldNEQ(FieldDeletedAt, v))
+}
+
+// DeletedAtIn applies the In predicate on the "deleted_at" field.
+func DeletedAtIn(vs ...time.Time) predicate.Label {
+	return predicate.Label(sql.FieldIn(FieldDeletedAt, vs...))
+}
+
+// DeletedAtNotIn applies the NotIn predicate on the "deleted_at" field.
+func DeletedAtNotIn(vs ...time.Time) predicate.Label {
+	return predicate.Label(sql.FieldNotIn(FieldDeletedAt, vs...))
+}
+
+// DeletedAtGT applies the GT predicate on the "deleted_at" field.
+func DeletedAtGT(v time.Time) predicate.Label {
+	return predicate.Label(sql.FieldGT(FieldDeletedAt, v))
+}
+
+// DeletedAtGTE applies the GTE predicate on the "deleted_at" field.
+func DeletedAtGTE(v time.Time) predicate.Label {
+	return predicate.Label(sql.FieldGTE(FieldDeletedAt, v))
+}
+
+// DeletedAtLT applies the LT predicate on the "deleted_at" field.
+func DeletedAtLT(v time.Time) predicate.Label {
+	return predicate.Label(sql.FieldLT(FieldDeletedAt, v))
+}
+
+// DeletedAtLTE applies the LTE predicate on the "deleted_at" field.
+func DeletedAtLTE(v time.Time) predicate.Label {
+	return predicate.Label(sql.FieldLTE(FieldDeletedAt, v))
+}
+
+// DeletedAtIsNil applies the IsNil predicate on the "deleted_at" field.
+func DeletedAtIsNil() predicate.Label {
+	return predicate.Label(sql.FieldIsNull(FieldDeletedAt))
+}
+
+// DeletedAtNotNil applies the NotNil predicate on the "deleted_at" field.
+func DeletedAtNotNil() predicate.Label {
+	return predicate.Label(sql.FieldNotNull(FieldDeletedAt))
+}
+
 // TypeEQ applies the EQ predicate on the "type" field.
 func TypeEQ(v int) predicate.Label {
 	return predicate.Label(sql.FieldEQ(FieldType, v))

+ 89 - 2
ent/label_create.go

@@ -65,6 +65,20 @@ func (lc *LabelCreate) SetNillableStatus(u *uint8) *LabelCreate {
 	return lc
 }
 
+// SetDeletedAt sets the "deleted_at" field.
+func (lc *LabelCreate) SetDeletedAt(t time.Time) *LabelCreate {
+	lc.mutation.SetDeletedAt(t)
+	return lc
+}
+
+// SetNillableDeletedAt sets the "deleted_at" field if the given value is not nil.
+func (lc *LabelCreate) SetNillableDeletedAt(t *time.Time) *LabelCreate {
+	if t != nil {
+		lc.SetDeletedAt(*t)
+	}
+	return lc
+}
+
 // SetType sets the "type" field.
 func (lc *LabelCreate) SetType(i int) *LabelCreate {
 	lc.mutation.SetType(i)
@@ -177,7 +191,9 @@ func (lc *LabelCreate) Mutation() *LabelMutation {
 
 // Save creates the Label in the database.
 func (lc *LabelCreate) Save(ctx context.Context) (*Label, error) {
-	lc.defaults()
+	if err := lc.defaults(); err != nil {
+		return nil, err
+	}
 	return withHooks(ctx, lc.sqlSave, lc.mutation, lc.hooks)
 }
 
@@ -204,12 +220,18 @@ func (lc *LabelCreate) ExecX(ctx context.Context) {
 }
 
 // defaults sets the default values of the builder before save.
-func (lc *LabelCreate) defaults() {
+func (lc *LabelCreate) defaults() error {
 	if _, ok := lc.mutation.CreatedAt(); !ok {
+		if label.DefaultCreatedAt == nil {
+			return fmt.Errorf("ent: uninitialized label.DefaultCreatedAt (forgotten import ent/runtime?)")
+		}
 		v := label.DefaultCreatedAt()
 		lc.mutation.SetCreatedAt(v)
 	}
 	if _, ok := lc.mutation.UpdatedAt(); !ok {
+		if label.DefaultUpdatedAt == nil {
+			return fmt.Errorf("ent: uninitialized label.DefaultUpdatedAt (forgotten import ent/runtime?)")
+		}
 		v := label.DefaultUpdatedAt()
 		lc.mutation.SetUpdatedAt(v)
 	}
@@ -241,6 +263,7 @@ func (lc *LabelCreate) defaults() {
 		v := label.DefaultOrganizationID
 		lc.mutation.SetOrganizationID(v)
 	}
+	return nil
 }
 
 // check runs all checks and user-defined validators on the builder.
@@ -308,6 +331,10 @@ func (lc *LabelCreate) createSpec() (*Label, *sqlgraph.CreateSpec) {
 		_spec.SetField(label.FieldStatus, field.TypeUint8, value)
 		_node.Status = value
 	}
+	if value, ok := lc.mutation.DeletedAt(); ok {
+		_spec.SetField(label.FieldDeletedAt, field.TypeTime, value)
+		_node.DeletedAt = value
+	}
 	if value, ok := lc.mutation.GetType(); ok {
 		_spec.SetField(label.FieldType, field.TypeInt, value)
 		_node.Type = value
@@ -436,6 +463,24 @@ func (u *LabelUpsert) ClearStatus() *LabelUpsert {
 	return u
 }
 
+// SetDeletedAt sets the "deleted_at" field.
+func (u *LabelUpsert) SetDeletedAt(v time.Time) *LabelUpsert {
+	u.Set(label.FieldDeletedAt, v)
+	return u
+}
+
+// UpdateDeletedAt sets the "deleted_at" field to the value that was provided on create.
+func (u *LabelUpsert) UpdateDeletedAt() *LabelUpsert {
+	u.SetExcluded(label.FieldDeletedAt)
+	return u
+}
+
+// ClearDeletedAt clears the value of the "deleted_at" field.
+func (u *LabelUpsert) ClearDeletedAt() *LabelUpsert {
+	u.SetNull(label.FieldDeletedAt)
+	return u
+}
+
 // SetType sets the "type" field.
 func (u *LabelUpsert) SetType(v int) *LabelUpsert {
 	u.Set(label.FieldType, v)
@@ -637,6 +682,27 @@ func (u *LabelUpsertOne) ClearStatus() *LabelUpsertOne {
 	})
 }
 
+// SetDeletedAt sets the "deleted_at" field.
+func (u *LabelUpsertOne) SetDeletedAt(v time.Time) *LabelUpsertOne {
+	return u.Update(func(s *LabelUpsert) {
+		s.SetDeletedAt(v)
+	})
+}
+
+// UpdateDeletedAt sets the "deleted_at" field to the value that was provided on create.
+func (u *LabelUpsertOne) UpdateDeletedAt() *LabelUpsertOne {
+	return u.Update(func(s *LabelUpsert) {
+		s.UpdateDeletedAt()
+	})
+}
+
+// ClearDeletedAt clears the value of the "deleted_at" field.
+func (u *LabelUpsertOne) ClearDeletedAt() *LabelUpsertOne {
+	return u.Update(func(s *LabelUpsert) {
+		s.ClearDeletedAt()
+	})
+}
+
 // SetType sets the "type" field.
 func (u *LabelUpsertOne) SetType(v int) *LabelUpsertOne {
 	return u.Update(func(s *LabelUpsert) {
@@ -1022,6 +1088,27 @@ func (u *LabelUpsertBulk) ClearStatus() *LabelUpsertBulk {
 	})
 }
 
+// SetDeletedAt sets the "deleted_at" field.
+func (u *LabelUpsertBulk) SetDeletedAt(v time.Time) *LabelUpsertBulk {
+	return u.Update(func(s *LabelUpsert) {
+		s.SetDeletedAt(v)
+	})
+}
+
+// UpdateDeletedAt sets the "deleted_at" field to the value that was provided on create.
+func (u *LabelUpsertBulk) UpdateDeletedAt() *LabelUpsertBulk {
+	return u.Update(func(s *LabelUpsert) {
+		s.UpdateDeletedAt()
+	})
+}
+
+// ClearDeletedAt clears the value of the "deleted_at" field.
+func (u *LabelUpsertBulk) ClearDeletedAt() *LabelUpsertBulk {
+	return u.Update(func(s *LabelUpsert) {
+		s.ClearDeletedAt()
+	})
+}
+
 // SetType sets the "type" field.
 func (u *LabelUpsertBulk) SetType(v int) *LabelUpsertBulk {
 	return u.Update(func(s *LabelUpsert) {

+ 68 - 4
ent/label_update.go

@@ -62,6 +62,26 @@ func (lu *LabelUpdate) ClearStatus() *LabelUpdate {
 	return lu
 }
 
+// SetDeletedAt sets the "deleted_at" field.
+func (lu *LabelUpdate) SetDeletedAt(t time.Time) *LabelUpdate {
+	lu.mutation.SetDeletedAt(t)
+	return lu
+}
+
+// SetNillableDeletedAt sets the "deleted_at" field if the given value is not nil.
+func (lu *LabelUpdate) SetNillableDeletedAt(t *time.Time) *LabelUpdate {
+	if t != nil {
+		lu.SetDeletedAt(*t)
+	}
+	return lu
+}
+
+// ClearDeletedAt clears the value of the "deleted_at" field.
+func (lu *LabelUpdate) ClearDeletedAt() *LabelUpdate {
+	lu.mutation.ClearDeletedAt()
+	return lu
+}
+
 // SetType sets the "type" field.
 func (lu *LabelUpdate) SetType(i int) *LabelUpdate {
 	lu.mutation.ResetType()
@@ -229,7 +249,9 @@ func (lu *LabelUpdate) RemoveLabelRelationships(l ...*LabelRelationship) *LabelU
 
 // Save executes the query and returns the number of nodes affected by the update operation.
 func (lu *LabelUpdate) Save(ctx context.Context) (int, error) {
-	lu.defaults()
+	if err := lu.defaults(); err != nil {
+		return 0, err
+	}
 	return withHooks(ctx, lu.sqlSave, lu.mutation, lu.hooks)
 }
 
@@ -256,11 +278,15 @@ func (lu *LabelUpdate) ExecX(ctx context.Context) {
 }
 
 // defaults sets the default values of the builder before save.
-func (lu *LabelUpdate) defaults() {
+func (lu *LabelUpdate) defaults() error {
 	if _, ok := lu.mutation.UpdatedAt(); !ok {
+		if label.UpdateDefaultUpdatedAt == nil {
+			return fmt.Errorf("ent: uninitialized label.UpdateDefaultUpdatedAt (forgotten import ent/runtime?)")
+		}
 		v := label.UpdateDefaultUpdatedAt()
 		lu.mutation.SetUpdatedAt(v)
 	}
+	return nil
 }
 
 func (lu *LabelUpdate) sqlSave(ctx context.Context) (n int, err error) {
@@ -284,6 +310,12 @@ func (lu *LabelUpdate) sqlSave(ctx context.Context) (n int, err error) {
 	if lu.mutation.StatusCleared() {
 		_spec.ClearField(label.FieldStatus, field.TypeUint8)
 	}
+	if value, ok := lu.mutation.DeletedAt(); ok {
+		_spec.SetField(label.FieldDeletedAt, field.TypeTime, value)
+	}
+	if lu.mutation.DeletedAtCleared() {
+		_spec.ClearField(label.FieldDeletedAt, field.TypeTime)
+	}
 	if value, ok := lu.mutation.GetType(); ok {
 		_spec.SetField(label.FieldType, field.TypeInt, value)
 	}
@@ -418,6 +450,26 @@ func (luo *LabelUpdateOne) ClearStatus() *LabelUpdateOne {
 	return luo
 }
 
+// SetDeletedAt sets the "deleted_at" field.
+func (luo *LabelUpdateOne) SetDeletedAt(t time.Time) *LabelUpdateOne {
+	luo.mutation.SetDeletedAt(t)
+	return luo
+}
+
+// SetNillableDeletedAt sets the "deleted_at" field if the given value is not nil.
+func (luo *LabelUpdateOne) SetNillableDeletedAt(t *time.Time) *LabelUpdateOne {
+	if t != nil {
+		luo.SetDeletedAt(*t)
+	}
+	return luo
+}
+
+// ClearDeletedAt clears the value of the "deleted_at" field.
+func (luo *LabelUpdateOne) ClearDeletedAt() *LabelUpdateOne {
+	luo.mutation.ClearDeletedAt()
+	return luo
+}
+
 // SetType sets the "type" field.
 func (luo *LabelUpdateOne) SetType(i int) *LabelUpdateOne {
 	luo.mutation.ResetType()
@@ -598,7 +650,9 @@ func (luo *LabelUpdateOne) Select(field string, fields ...string) *LabelUpdateOn
 
 // Save executes the query and returns the updated Label entity.
 func (luo *LabelUpdateOne) Save(ctx context.Context) (*Label, error) {
-	luo.defaults()
+	if err := luo.defaults(); err != nil {
+		return nil, err
+	}
 	return withHooks(ctx, luo.sqlSave, luo.mutation, luo.hooks)
 }
 
@@ -625,11 +679,15 @@ func (luo *LabelUpdateOne) ExecX(ctx context.Context) {
 }
 
 // defaults sets the default values of the builder before save.
-func (luo *LabelUpdateOne) defaults() {
+func (luo *LabelUpdateOne) defaults() error {
 	if _, ok := luo.mutation.UpdatedAt(); !ok {
+		if label.UpdateDefaultUpdatedAt == nil {
+			return fmt.Errorf("ent: uninitialized label.UpdateDefaultUpdatedAt (forgotten import ent/runtime?)")
+		}
 		v := label.UpdateDefaultUpdatedAt()
 		luo.mutation.SetUpdatedAt(v)
 	}
+	return nil
 }
 
 func (luo *LabelUpdateOne) sqlSave(ctx context.Context) (_node *Label, err error) {
@@ -670,6 +728,12 @@ func (luo *LabelUpdateOne) sqlSave(ctx context.Context) (_node *Label, err error
 	if luo.mutation.StatusCleared() {
 		_spec.ClearField(label.FieldStatus, field.TypeUint8)
 	}
+	if value, ok := luo.mutation.DeletedAt(); ok {
+		_spec.SetField(label.FieldDeletedAt, field.TypeTime, value)
+	}
+	if luo.mutation.DeletedAtCleared() {
+		_spec.ClearField(label.FieldDeletedAt, field.TypeTime)
+	}
 	if value, ok := luo.mutation.GetType(); ok {
 		_spec.SetField(label.FieldType, field.TypeInt, value)
 	}

+ 12 - 1
ent/labelrelationship.go

@@ -25,6 +25,8 @@ type LabelRelationship struct {
 	UpdatedAt time.Time `json:"updated_at,omitempty"`
 	// Status 1: normal 2: ban | 状态 1 正常 2 禁用
 	Status uint8 `json:"status,omitempty"`
+	// Delete Time | 删除日期
+	DeletedAt time.Time `json:"deleted_at,omitempty"`
 	// 标签 ID
 	LabelID uint64 `json:"label_id,omitempty"`
 	// 联系人 ID
@@ -77,7 +79,7 @@ func (*LabelRelationship) scanValues(columns []string) ([]any, error) {
 		switch columns[i] {
 		case labelrelationship.FieldID, labelrelationship.FieldStatus, labelrelationship.FieldLabelID, labelrelationship.FieldContactID, labelrelationship.FieldOrganizationID:
 			values[i] = new(sql.NullInt64)
-		case labelrelationship.FieldCreatedAt, labelrelationship.FieldUpdatedAt:
+		case labelrelationship.FieldCreatedAt, labelrelationship.FieldUpdatedAt, labelrelationship.FieldDeletedAt:
 			values[i] = new(sql.NullTime)
 		default:
 			values[i] = new(sql.UnknownType)
@@ -118,6 +120,12 @@ func (lr *LabelRelationship) assignValues(columns []string, values []any) error
 			} else if value.Valid {
 				lr.Status = uint8(value.Int64)
 			}
+		case labelrelationship.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 {
+				lr.DeletedAt = value.Time
+			}
 		case labelrelationship.FieldLabelID:
 			if value, ok := values[i].(*sql.NullInt64); !ok {
 				return fmt.Errorf("unexpected type %T for field label_id", values[i])
@@ -191,6 +199,9 @@ func (lr *LabelRelationship) String() string {
 	builder.WriteString("status=")
 	builder.WriteString(fmt.Sprintf("%v", lr.Status))
 	builder.WriteString(", ")
+	builder.WriteString("deleted_at=")
+	builder.WriteString(lr.DeletedAt.Format(time.ANSIC))
+	builder.WriteString(", ")
 	builder.WriteString("label_id=")
 	builder.WriteString(fmt.Sprintf("%v", lr.LabelID))
 	builder.WriteString(", ")

+ 16 - 0
ent/labelrelationship/labelrelationship.go

@@ -5,6 +5,7 @@ package labelrelationship
 import (
 	"time"
 
+	"entgo.io/ent"
 	"entgo.io/ent/dialect/sql"
 	"entgo.io/ent/dialect/sql/sqlgraph"
 )
@@ -20,6 +21,8 @@ const (
 	FieldUpdatedAt = "updated_at"
 	// FieldStatus holds the string denoting the status field in the database.
 	FieldStatus = "status"
+	// FieldDeletedAt holds the string denoting the deleted_at field in the database.
+	FieldDeletedAt = "deleted_at"
 	// FieldLabelID holds the string denoting the label_id field in the database.
 	FieldLabelID = "label_id"
 	// FieldContactID holds the string denoting the contact_id field in the database.
@@ -54,6 +57,7 @@ var Columns = []string{
 	FieldCreatedAt,
 	FieldUpdatedAt,
 	FieldStatus,
+	FieldDeletedAt,
 	FieldLabelID,
 	FieldContactID,
 	FieldOrganizationID,
@@ -69,7 +73,14 @@ func ValidColumn(column string) bool {
 	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.
@@ -109,6 +120,11 @@ func ByStatus(opts ...sql.OrderTermOption) OrderOption {
 	return sql.OrderByField(FieldStatus, opts...).ToFunc()
 }
 
+// ByDeletedAt orders the results by the deleted_at field.
+func ByDeletedAt(opts ...sql.OrderTermOption) OrderOption {
+	return sql.OrderByField(FieldDeletedAt, opts...).ToFunc()
+}
+
 // ByLabelID orders the results by the label_id field.
 func ByLabelID(opts ...sql.OrderTermOption) OrderOption {
 	return sql.OrderByField(FieldLabelID, opts...).ToFunc()

+ 55 - 0
ent/labelrelationship/where.go

@@ -70,6 +70,11 @@ func Status(v uint8) predicate.LabelRelationship {
 	return predicate.LabelRelationship(sql.FieldEQ(FieldStatus, v))
 }
 
+// DeletedAt applies equality check predicate on the "deleted_at" field. It's identical to DeletedAtEQ.
+func DeletedAt(v time.Time) predicate.LabelRelationship {
+	return predicate.LabelRelationship(sql.FieldEQ(FieldDeletedAt, v))
+}
+
 // LabelID applies equality check predicate on the "label_id" field. It's identical to LabelIDEQ.
 func LabelID(v uint64) predicate.LabelRelationship {
 	return predicate.LabelRelationship(sql.FieldEQ(FieldLabelID, v))
@@ -215,6 +220,56 @@ func StatusNotNil() predicate.LabelRelationship {
 	return predicate.LabelRelationship(sql.FieldNotNull(FieldStatus))
 }
 
+// DeletedAtEQ applies the EQ predicate on the "deleted_at" field.
+func DeletedAtEQ(v time.Time) predicate.LabelRelationship {
+	return predicate.LabelRelationship(sql.FieldEQ(FieldDeletedAt, v))
+}
+
+// DeletedAtNEQ applies the NEQ predicate on the "deleted_at" field.
+func DeletedAtNEQ(v time.Time) predicate.LabelRelationship {
+	return predicate.LabelRelationship(sql.FieldNEQ(FieldDeletedAt, v))
+}
+
+// DeletedAtIn applies the In predicate on the "deleted_at" field.
+func DeletedAtIn(vs ...time.Time) predicate.LabelRelationship {
+	return predicate.LabelRelationship(sql.FieldIn(FieldDeletedAt, vs...))
+}
+
+// DeletedAtNotIn applies the NotIn predicate on the "deleted_at" field.
+func DeletedAtNotIn(vs ...time.Time) predicate.LabelRelationship {
+	return predicate.LabelRelationship(sql.FieldNotIn(FieldDeletedAt, vs...))
+}
+
+// DeletedAtGT applies the GT predicate on the "deleted_at" field.
+func DeletedAtGT(v time.Time) predicate.LabelRelationship {
+	return predicate.LabelRelationship(sql.FieldGT(FieldDeletedAt, v))
+}
+
+// DeletedAtGTE applies the GTE predicate on the "deleted_at" field.
+func DeletedAtGTE(v time.Time) predicate.LabelRelationship {
+	return predicate.LabelRelationship(sql.FieldGTE(FieldDeletedAt, v))
+}
+
+// DeletedAtLT applies the LT predicate on the "deleted_at" field.
+func DeletedAtLT(v time.Time) predicate.LabelRelationship {
+	return predicate.LabelRelationship(sql.FieldLT(FieldDeletedAt, v))
+}
+
+// DeletedAtLTE applies the LTE predicate on the "deleted_at" field.
+func DeletedAtLTE(v time.Time) predicate.LabelRelationship {
+	return predicate.LabelRelationship(sql.FieldLTE(FieldDeletedAt, v))
+}
+
+// DeletedAtIsNil applies the IsNil predicate on the "deleted_at" field.
+func DeletedAtIsNil() predicate.LabelRelationship {
+	return predicate.LabelRelationship(sql.FieldIsNull(FieldDeletedAt))
+}
+
+// DeletedAtNotNil applies the NotNil predicate on the "deleted_at" field.
+func DeletedAtNotNil() predicate.LabelRelationship {
+	return predicate.LabelRelationship(sql.FieldNotNull(FieldDeletedAt))
+}
+
 // LabelIDEQ applies the EQ predicate on the "label_id" field.
 func LabelIDEQ(v uint64) predicate.LabelRelationship {
 	return predicate.LabelRelationship(sql.FieldEQ(FieldLabelID, v))

+ 89 - 2
ent/labelrelationship_create.go

@@ -66,6 +66,20 @@ func (lrc *LabelRelationshipCreate) SetNillableStatus(u *uint8) *LabelRelationsh
 	return lrc
 }
 
+// SetDeletedAt sets the "deleted_at" field.
+func (lrc *LabelRelationshipCreate) SetDeletedAt(t time.Time) *LabelRelationshipCreate {
+	lrc.mutation.SetDeletedAt(t)
+	return lrc
+}
+
+// SetNillableDeletedAt sets the "deleted_at" field if the given value is not nil.
+func (lrc *LabelRelationshipCreate) SetNillableDeletedAt(t *time.Time) *LabelRelationshipCreate {
+	if t != nil {
+		lrc.SetDeletedAt(*t)
+	}
+	return lrc
+}
+
 // SetLabelID sets the "label_id" field.
 func (lrc *LabelRelationshipCreate) SetLabelID(u uint64) *LabelRelationshipCreate {
 	lrc.mutation.SetLabelID(u)
@@ -143,7 +157,9 @@ func (lrc *LabelRelationshipCreate) Mutation() *LabelRelationshipMutation {
 
 // Save creates the LabelRelationship in the database.
 func (lrc *LabelRelationshipCreate) Save(ctx context.Context) (*LabelRelationship, error) {
-	lrc.defaults()
+	if err := lrc.defaults(); err != nil {
+		return nil, err
+	}
 	return withHooks(ctx, lrc.sqlSave, lrc.mutation, lrc.hooks)
 }
 
@@ -170,12 +186,18 @@ func (lrc *LabelRelationshipCreate) ExecX(ctx context.Context) {
 }
 
 // defaults sets the default values of the builder before save.
-func (lrc *LabelRelationshipCreate) defaults() {
+func (lrc *LabelRelationshipCreate) defaults() error {
 	if _, ok := lrc.mutation.CreatedAt(); !ok {
+		if labelrelationship.DefaultCreatedAt == nil {
+			return fmt.Errorf("ent: uninitialized labelrelationship.DefaultCreatedAt (forgotten import ent/runtime?)")
+		}
 		v := labelrelationship.DefaultCreatedAt()
 		lrc.mutation.SetCreatedAt(v)
 	}
 	if _, ok := lrc.mutation.UpdatedAt(); !ok {
+		if labelrelationship.DefaultUpdatedAt == nil {
+			return fmt.Errorf("ent: uninitialized labelrelationship.DefaultUpdatedAt (forgotten import ent/runtime?)")
+		}
 		v := labelrelationship.DefaultUpdatedAt()
 		lrc.mutation.SetUpdatedAt(v)
 	}
@@ -195,6 +217,7 @@ func (lrc *LabelRelationshipCreate) defaults() {
 		v := labelrelationship.DefaultOrganizationID
 		lrc.mutation.SetOrganizationID(v)
 	}
+	return nil
 }
 
 // check runs all checks and user-defined validators on the builder.
@@ -262,6 +285,10 @@ func (lrc *LabelRelationshipCreate) createSpec() (*LabelRelationship, *sqlgraph.
 		_spec.SetField(labelrelationship.FieldStatus, field.TypeUint8, value)
 		_node.Status = value
 	}
+	if value, ok := lrc.mutation.DeletedAt(); ok {
+		_spec.SetField(labelrelationship.FieldDeletedAt, field.TypeTime, value)
+		_node.DeletedAt = value
+	}
 	if value, ok := lrc.mutation.OrganizationID(); ok {
 		_spec.SetField(labelrelationship.FieldOrganizationID, field.TypeUint64, value)
 		_node.OrganizationID = value
@@ -388,6 +415,24 @@ func (u *LabelRelationshipUpsert) ClearStatus() *LabelRelationshipUpsert {
 	return u
 }
 
+// SetDeletedAt sets the "deleted_at" field.
+func (u *LabelRelationshipUpsert) SetDeletedAt(v time.Time) *LabelRelationshipUpsert {
+	u.Set(labelrelationship.FieldDeletedAt, v)
+	return u
+}
+
+// UpdateDeletedAt sets the "deleted_at" field to the value that was provided on create.
+func (u *LabelRelationshipUpsert) UpdateDeletedAt() *LabelRelationshipUpsert {
+	u.SetExcluded(labelrelationship.FieldDeletedAt)
+	return u
+}
+
+// ClearDeletedAt clears the value of the "deleted_at" field.
+func (u *LabelRelationshipUpsert) ClearDeletedAt() *LabelRelationshipUpsert {
+	u.SetNull(labelrelationship.FieldDeletedAt)
+	return u
+}
+
 // SetLabelID sets the "label_id" field.
 func (u *LabelRelationshipUpsert) SetLabelID(v uint64) *LabelRelationshipUpsert {
 	u.Set(labelrelationship.FieldLabelID, v)
@@ -529,6 +574,27 @@ func (u *LabelRelationshipUpsertOne) ClearStatus() *LabelRelationshipUpsertOne {
 	})
 }
 
+// SetDeletedAt sets the "deleted_at" field.
+func (u *LabelRelationshipUpsertOne) SetDeletedAt(v time.Time) *LabelRelationshipUpsertOne {
+	return u.Update(func(s *LabelRelationshipUpsert) {
+		s.SetDeletedAt(v)
+	})
+}
+
+// UpdateDeletedAt sets the "deleted_at" field to the value that was provided on create.
+func (u *LabelRelationshipUpsertOne) UpdateDeletedAt() *LabelRelationshipUpsertOne {
+	return u.Update(func(s *LabelRelationshipUpsert) {
+		s.UpdateDeletedAt()
+	})
+}
+
+// ClearDeletedAt clears the value of the "deleted_at" field.
+func (u *LabelRelationshipUpsertOne) ClearDeletedAt() *LabelRelationshipUpsertOne {
+	return u.Update(func(s *LabelRelationshipUpsert) {
+		s.ClearDeletedAt()
+	})
+}
+
 // SetLabelID sets the "label_id" field.
 func (u *LabelRelationshipUpsertOne) SetLabelID(v uint64) *LabelRelationshipUpsertOne {
 	return u.Update(func(s *LabelRelationshipUpsert) {
@@ -844,6 +910,27 @@ func (u *LabelRelationshipUpsertBulk) ClearStatus() *LabelRelationshipUpsertBulk
 	})
 }
 
+// SetDeletedAt sets the "deleted_at" field.
+func (u *LabelRelationshipUpsertBulk) SetDeletedAt(v time.Time) *LabelRelationshipUpsertBulk {
+	return u.Update(func(s *LabelRelationshipUpsert) {
+		s.SetDeletedAt(v)
+	})
+}
+
+// UpdateDeletedAt sets the "deleted_at" field to the value that was provided on create.
+func (u *LabelRelationshipUpsertBulk) UpdateDeletedAt() *LabelRelationshipUpsertBulk {
+	return u.Update(func(s *LabelRelationshipUpsert) {
+		s.UpdateDeletedAt()
+	})
+}
+
+// ClearDeletedAt clears the value of the "deleted_at" field.
+func (u *LabelRelationshipUpsertBulk) ClearDeletedAt() *LabelRelationshipUpsertBulk {
+	return u.Update(func(s *LabelRelationshipUpsert) {
+		s.ClearDeletedAt()
+	})
+}
+
 // SetLabelID sets the "label_id" field.
 func (u *LabelRelationshipUpsertBulk) SetLabelID(v uint64) *LabelRelationshipUpsertBulk {
 	return u.Update(func(s *LabelRelationshipUpsert) {

+ 68 - 4
ent/labelrelationship_update.go

@@ -63,6 +63,26 @@ func (lru *LabelRelationshipUpdate) ClearStatus() *LabelRelationshipUpdate {
 	return lru
 }
 
+// SetDeletedAt sets the "deleted_at" field.
+func (lru *LabelRelationshipUpdate) SetDeletedAt(t time.Time) *LabelRelationshipUpdate {
+	lru.mutation.SetDeletedAt(t)
+	return lru
+}
+
+// SetNillableDeletedAt sets the "deleted_at" field if the given value is not nil.
+func (lru *LabelRelationshipUpdate) SetNillableDeletedAt(t *time.Time) *LabelRelationshipUpdate {
+	if t != nil {
+		lru.SetDeletedAt(*t)
+	}
+	return lru
+}
+
+// ClearDeletedAt clears the value of the "deleted_at" field.
+func (lru *LabelRelationshipUpdate) ClearDeletedAt() *LabelRelationshipUpdate {
+	lru.mutation.ClearDeletedAt()
+	return lru
+}
+
 // SetLabelID sets the "label_id" field.
 func (lru *LabelRelationshipUpdate) SetLabelID(u uint64) *LabelRelationshipUpdate {
 	lru.mutation.SetLabelID(u)
@@ -159,7 +179,9 @@ func (lru *LabelRelationshipUpdate) ClearLabels() *LabelRelationshipUpdate {
 
 // Save executes the query and returns the number of nodes affected by the update operation.
 func (lru *LabelRelationshipUpdate) Save(ctx context.Context) (int, error) {
-	lru.defaults()
+	if err := lru.defaults(); err != nil {
+		return 0, err
+	}
 	return withHooks(ctx, lru.sqlSave, lru.mutation, lru.hooks)
 }
 
@@ -186,11 +208,15 @@ func (lru *LabelRelationshipUpdate) ExecX(ctx context.Context) {
 }
 
 // defaults sets the default values of the builder before save.
-func (lru *LabelRelationshipUpdate) defaults() {
+func (lru *LabelRelationshipUpdate) defaults() error {
 	if _, ok := lru.mutation.UpdatedAt(); !ok {
+		if labelrelationship.UpdateDefaultUpdatedAt == nil {
+			return fmt.Errorf("ent: uninitialized labelrelationship.UpdateDefaultUpdatedAt (forgotten import ent/runtime?)")
+		}
 		v := labelrelationship.UpdateDefaultUpdatedAt()
 		lru.mutation.SetUpdatedAt(v)
 	}
+	return nil
 }
 
 // check runs all checks and user-defined validators on the builder.
@@ -228,6 +254,12 @@ func (lru *LabelRelationshipUpdate) sqlSave(ctx context.Context) (n int, err err
 	if lru.mutation.StatusCleared() {
 		_spec.ClearField(labelrelationship.FieldStatus, field.TypeUint8)
 	}
+	if value, ok := lru.mutation.DeletedAt(); ok {
+		_spec.SetField(labelrelationship.FieldDeletedAt, field.TypeTime, value)
+	}
+	if lru.mutation.DeletedAtCleared() {
+		_spec.ClearField(labelrelationship.FieldDeletedAt, field.TypeTime)
+	}
 	if value, ok := lru.mutation.OrganizationID(); ok {
 		_spec.SetField(labelrelationship.FieldOrganizationID, field.TypeUint64, value)
 	}
@@ -348,6 +380,26 @@ func (lruo *LabelRelationshipUpdateOne) ClearStatus() *LabelRelationshipUpdateOn
 	return lruo
 }
 
+// SetDeletedAt sets the "deleted_at" field.
+func (lruo *LabelRelationshipUpdateOne) SetDeletedAt(t time.Time) *LabelRelationshipUpdateOne {
+	lruo.mutation.SetDeletedAt(t)
+	return lruo
+}
+
+// SetNillableDeletedAt sets the "deleted_at" field if the given value is not nil.
+func (lruo *LabelRelationshipUpdateOne) SetNillableDeletedAt(t *time.Time) *LabelRelationshipUpdateOne {
+	if t != nil {
+		lruo.SetDeletedAt(*t)
+	}
+	return lruo
+}
+
+// ClearDeletedAt clears the value of the "deleted_at" field.
+func (lruo *LabelRelationshipUpdateOne) ClearDeletedAt() *LabelRelationshipUpdateOne {
+	lruo.mutation.ClearDeletedAt()
+	return lruo
+}
+
 // SetLabelID sets the "label_id" field.
 func (lruo *LabelRelationshipUpdateOne) SetLabelID(u uint64) *LabelRelationshipUpdateOne {
 	lruo.mutation.SetLabelID(u)
@@ -457,7 +509,9 @@ func (lruo *LabelRelationshipUpdateOne) Select(field string, fields ...string) *
 
 // Save executes the query and returns the updated LabelRelationship entity.
 func (lruo *LabelRelationshipUpdateOne) Save(ctx context.Context) (*LabelRelationship, error) {
-	lruo.defaults()
+	if err := lruo.defaults(); err != nil {
+		return nil, err
+	}
 	return withHooks(ctx, lruo.sqlSave, lruo.mutation, lruo.hooks)
 }
 
@@ -484,11 +538,15 @@ func (lruo *LabelRelationshipUpdateOne) ExecX(ctx context.Context) {
 }
 
 // defaults sets the default values of the builder before save.
-func (lruo *LabelRelationshipUpdateOne) defaults() {
+func (lruo *LabelRelationshipUpdateOne) defaults() error {
 	if _, ok := lruo.mutation.UpdatedAt(); !ok {
+		if labelrelationship.UpdateDefaultUpdatedAt == nil {
+			return fmt.Errorf("ent: uninitialized labelrelationship.UpdateDefaultUpdatedAt (forgotten import ent/runtime?)")
+		}
 		v := labelrelationship.UpdateDefaultUpdatedAt()
 		lruo.mutation.SetUpdatedAt(v)
 	}
+	return nil
 }
 
 // check runs all checks and user-defined validators on the builder.
@@ -543,6 +601,12 @@ func (lruo *LabelRelationshipUpdateOne) sqlSave(ctx context.Context) (_node *Lab
 	if lruo.mutation.StatusCleared() {
 		_spec.ClearField(labelrelationship.FieldStatus, field.TypeUint8)
 	}
+	if value, ok := lruo.mutation.DeletedAt(); ok {
+		_spec.SetField(labelrelationship.FieldDeletedAt, field.TypeTime, value)
+	}
+	if lruo.mutation.DeletedAtCleared() {
+		_spec.ClearField(labelrelationship.FieldDeletedAt, field.TypeTime)
+	}
 	if value, ok := lruo.mutation.OrganizationID(); ok {
 		_spec.SetField(labelrelationship.FieldOrganizationID, field.TypeUint64, value)
 	}

+ 6 - 4
ent/migrate/schema.go

@@ -546,6 +546,7 @@ var (
 		{Name: "created_at", Type: field.TypeTime, Comment: "Create Time | 创建日期"},
 		{Name: "updated_at", Type: field.TypeTime, Comment: "Update Time | 修改日期"},
 		{Name: "status", Type: field.TypeUint8, Nullable: true, Comment: "Status 1: normal 2: ban | 状态 1 正常 2 禁用", Default: 1},
+		{Name: "deleted_at", Type: field.TypeTime, Nullable: true, Comment: "Delete Time | 删除日期"},
 		{Name: "type", Type: field.TypeInt, Comment: "标签类型:1好友,2群组,3公众号,4企业微信联系人", Default: 1},
 		{Name: "name", Type: field.TypeString, Comment: "标签名称", Default: ""},
 		{Name: "from", Type: field.TypeInt, Comment: "标签来源:1后台创建 2个微同步", Default: 1},
@@ -562,7 +563,7 @@ var (
 			{
 				Name:    "label_name_organization_id",
 				Unique:  true,
-				Columns: []*schema.Column{LabelColumns[5], LabelColumns[9]},
+				Columns: []*schema.Column{LabelColumns[6], LabelColumns[10]},
 			},
 		},
 	}
@@ -595,6 +596,7 @@ var (
 		{Name: "created_at", Type: field.TypeTime, Comment: "Create Time | 创建日期"},
 		{Name: "updated_at", Type: field.TypeTime, Comment: "Update Time | 修改日期"},
 		{Name: "status", Type: field.TypeUint8, Nullable: true, Comment: "Status 1: normal 2: ban | 状态 1 正常 2 禁用", Default: 1},
+		{Name: "deleted_at", Type: field.TypeTime, Nullable: true, Comment: "Delete Time | 删除日期"},
 		{Name: "organization_id", Type: field.TypeUint64, Nullable: true, Comment: "机构 ID", Default: 1},
 		{Name: "contact_id", Type: field.TypeUint64, Comment: "联系人 ID", Default: 1},
 		{Name: "label_id", Type: field.TypeUint64, Comment: "标签 ID", Default: 1},
@@ -607,13 +609,13 @@ var (
 		ForeignKeys: []*schema.ForeignKey{
 			{
 				Symbol:     "label_relationship_contact_contact_relationships",
-				Columns:    []*schema.Column{LabelRelationshipColumns[5]},
+				Columns:    []*schema.Column{LabelRelationshipColumns[6]},
 				RefColumns: []*schema.Column{ContactColumns[0]},
 				OnDelete:   schema.NoAction,
 			},
 			{
 				Symbol:     "label_relationship_label_label_relationships",
-				Columns:    []*schema.Column{LabelRelationshipColumns[6]},
+				Columns:    []*schema.Column{LabelRelationshipColumns[7]},
 				RefColumns: []*schema.Column{LabelColumns[0]},
 				OnDelete:   schema.NoAction,
 			},
@@ -622,7 +624,7 @@ var (
 			{
 				Name:    "u_label_contact",
 				Unique:  true,
-				Columns: []*schema.Column{LabelRelationshipColumns[6], LabelRelationshipColumns[5]},
+				Columns: []*schema.Column{LabelRelationshipColumns[7], LabelRelationshipColumns[6]},
 			},
 		},
 	}

+ 148 - 2
ent/mutation.go

@@ -21133,6 +21133,7 @@ type LabelMutation struct {
 	updated_at                 *time.Time
 	status                     *uint8
 	addstatus                  *int8
+	deleted_at                 *time.Time
 	_type                      *int
 	add_type                   *int
 	name                       *string
@@ -21398,6 +21399,55 @@ func (m *LabelMutation) ResetStatus() {
 	delete(m.clearedFields, label.FieldStatus)
 }
 
+// SetDeletedAt sets the "deleted_at" field.
+func (m *LabelMutation) SetDeletedAt(t time.Time) {
+	m.deleted_at = &t
+}
+
+// DeletedAt returns the value of the "deleted_at" field in the mutation.
+func (m *LabelMutation) 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 Label entity.
+// If the Label 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 *LabelMutation) 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 *LabelMutation) ClearDeletedAt() {
+	m.deleted_at = nil
+	m.clearedFields[label.FieldDeletedAt] = struct{}{}
+}
+
+// DeletedAtCleared returns if the "deleted_at" field was cleared in this mutation.
+func (m *LabelMutation) DeletedAtCleared() bool {
+	_, ok := m.clearedFields[label.FieldDeletedAt]
+	return ok
+}
+
+// ResetDeletedAt resets all changes to the "deleted_at" field.
+func (m *LabelMutation) ResetDeletedAt() {
+	m.deleted_at = nil
+	delete(m.clearedFields, label.FieldDeletedAt)
+}
+
 // SetType sets the "type" field.
 func (m *LabelMutation) SetType(i int) {
 	m._type = &i
@@ -21809,7 +21859,7 @@ func (m *LabelMutation) Type() string {
 // order to get all numeric fields that were incremented/decremented, call
 // AddedFields().
 func (m *LabelMutation) Fields() []string {
-	fields := make([]string, 0, 9)
+	fields := make([]string, 0, 10)
 	if m.created_at != nil {
 		fields = append(fields, label.FieldCreatedAt)
 	}
@@ -21819,6 +21869,9 @@ func (m *LabelMutation) Fields() []string {
 	if m.status != nil {
 		fields = append(fields, label.FieldStatus)
 	}
+	if m.deleted_at != nil {
+		fields = append(fields, label.FieldDeletedAt)
+	}
 	if m._type != nil {
 		fields = append(fields, label.FieldType)
 	}
@@ -21851,6 +21904,8 @@ func (m *LabelMutation) Field(name string) (ent.Value, bool) {
 		return m.UpdatedAt()
 	case label.FieldStatus:
 		return m.Status()
+	case label.FieldDeletedAt:
+		return m.DeletedAt()
 	case label.FieldType:
 		return m.GetType()
 	case label.FieldName:
@@ -21878,6 +21933,8 @@ func (m *LabelMutation) OldField(ctx context.Context, name string) (ent.Value, e
 		return m.OldUpdatedAt(ctx)
 	case label.FieldStatus:
 		return m.OldStatus(ctx)
+	case label.FieldDeletedAt:
+		return m.OldDeletedAt(ctx)
 	case label.FieldType:
 		return m.OldType(ctx)
 	case label.FieldName:
@@ -21920,6 +21977,13 @@ func (m *LabelMutation) SetField(name string, value ent.Value) error {
 		}
 		m.SetStatus(v)
 		return nil
+	case label.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 label.FieldType:
 		v, ok := value.(int)
 		if !ok {
@@ -22058,6 +22122,9 @@ func (m *LabelMutation) ClearedFields() []string {
 	if m.FieldCleared(label.FieldStatus) {
 		fields = append(fields, label.FieldStatus)
 	}
+	if m.FieldCleared(label.FieldDeletedAt) {
+		fields = append(fields, label.FieldDeletedAt)
+	}
 	if m.FieldCleared(label.FieldConditions) {
 		fields = append(fields, label.FieldConditions)
 	}
@@ -22081,6 +22148,9 @@ func (m *LabelMutation) ClearField(name string) error {
 	case label.FieldStatus:
 		m.ClearStatus()
 		return nil
+	case label.FieldDeletedAt:
+		m.ClearDeletedAt()
+		return nil
 	case label.FieldConditions:
 		m.ClearConditions()
 		return nil
@@ -22104,6 +22174,9 @@ func (m *LabelMutation) ResetField(name string) error {
 	case label.FieldStatus:
 		m.ResetStatus()
 		return nil
+	case label.FieldDeletedAt:
+		m.ResetDeletedAt()
+		return nil
 	case label.FieldType:
 		m.ResetType()
 		return nil
@@ -22914,6 +22987,7 @@ type LabelRelationshipMutation struct {
 	updated_at         *time.Time
 	status             *uint8
 	addstatus          *int8
+	deleted_at         *time.Time
 	organization_id    *uint64
 	addorganization_id *int64
 	clearedFields      map[string]struct{}
@@ -23172,6 +23246,55 @@ func (m *LabelRelationshipMutation) ResetStatus() {
 	delete(m.clearedFields, labelrelationship.FieldStatus)
 }
 
+// SetDeletedAt sets the "deleted_at" field.
+func (m *LabelRelationshipMutation) SetDeletedAt(t time.Time) {
+	m.deleted_at = &t
+}
+
+// DeletedAt returns the value of the "deleted_at" field in the mutation.
+func (m *LabelRelationshipMutation) 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 LabelRelationship entity.
+// If the LabelRelationship 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 *LabelRelationshipMutation) 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 *LabelRelationshipMutation) ClearDeletedAt() {
+	m.deleted_at = nil
+	m.clearedFields[labelrelationship.FieldDeletedAt] = struct{}{}
+}
+
+// DeletedAtCleared returns if the "deleted_at" field was cleared in this mutation.
+func (m *LabelRelationshipMutation) DeletedAtCleared() bool {
+	_, ok := m.clearedFields[labelrelationship.FieldDeletedAt]
+	return ok
+}
+
+// ResetDeletedAt resets all changes to the "deleted_at" field.
+func (m *LabelRelationshipMutation) ResetDeletedAt() {
+	m.deleted_at = nil
+	delete(m.clearedFields, labelrelationship.FieldDeletedAt)
+}
+
 // SetLabelID sets the "label_id" field.
 func (m *LabelRelationshipMutation) SetLabelID(u uint64) {
 	m.labels = &u
@@ -23428,7 +23551,7 @@ func (m *LabelRelationshipMutation) Type() string {
 // order to get all numeric fields that were incremented/decremented, call
 // AddedFields().
 func (m *LabelRelationshipMutation) Fields() []string {
-	fields := make([]string, 0, 6)
+	fields := make([]string, 0, 7)
 	if m.created_at != nil {
 		fields = append(fields, labelrelationship.FieldCreatedAt)
 	}
@@ -23438,6 +23561,9 @@ func (m *LabelRelationshipMutation) Fields() []string {
 	if m.status != nil {
 		fields = append(fields, labelrelationship.FieldStatus)
 	}
+	if m.deleted_at != nil {
+		fields = append(fields, labelrelationship.FieldDeletedAt)
+	}
 	if m.labels != nil {
 		fields = append(fields, labelrelationship.FieldLabelID)
 	}
@@ -23461,6 +23587,8 @@ func (m *LabelRelationshipMutation) Field(name string) (ent.Value, bool) {
 		return m.UpdatedAt()
 	case labelrelationship.FieldStatus:
 		return m.Status()
+	case labelrelationship.FieldDeletedAt:
+		return m.DeletedAt()
 	case labelrelationship.FieldLabelID:
 		return m.LabelID()
 	case labelrelationship.FieldContactID:
@@ -23482,6 +23610,8 @@ func (m *LabelRelationshipMutation) OldField(ctx context.Context, name string) (
 		return m.OldUpdatedAt(ctx)
 	case labelrelationship.FieldStatus:
 		return m.OldStatus(ctx)
+	case labelrelationship.FieldDeletedAt:
+		return m.OldDeletedAt(ctx)
 	case labelrelationship.FieldLabelID:
 		return m.OldLabelID(ctx)
 	case labelrelationship.FieldContactID:
@@ -23518,6 +23648,13 @@ func (m *LabelRelationshipMutation) SetField(name string, value ent.Value) error
 		}
 		m.SetStatus(v)
 		return nil
+	case labelrelationship.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 labelrelationship.FieldLabelID:
 		v, ok := value.(uint64)
 		if !ok {
@@ -23599,6 +23736,9 @@ func (m *LabelRelationshipMutation) ClearedFields() []string {
 	if m.FieldCleared(labelrelationship.FieldStatus) {
 		fields = append(fields, labelrelationship.FieldStatus)
 	}
+	if m.FieldCleared(labelrelationship.FieldDeletedAt) {
+		fields = append(fields, labelrelationship.FieldDeletedAt)
+	}
 	if m.FieldCleared(labelrelationship.FieldOrganizationID) {
 		fields = append(fields, labelrelationship.FieldOrganizationID)
 	}
@@ -23619,6 +23759,9 @@ func (m *LabelRelationshipMutation) ClearField(name string) error {
 	case labelrelationship.FieldStatus:
 		m.ClearStatus()
 		return nil
+	case labelrelationship.FieldDeletedAt:
+		m.ClearDeletedAt()
+		return nil
 	case labelrelationship.FieldOrganizationID:
 		m.ClearOrganizationID()
 		return nil
@@ -23639,6 +23782,9 @@ func (m *LabelRelationshipMutation) ResetField(name string) error {
 	case labelrelationship.FieldStatus:
 		m.ResetStatus()
 		return nil
+	case labelrelationship.FieldDeletedAt:
+		m.ResetDeletedAt()
+		return nil
 	case labelrelationship.FieldLabelID:
 		m.ResetLabelID()
 		return nil

+ 8 - 0
ent/runtime/runtime.go

@@ -859,6 +859,10 @@ func init() {
 	// employeeconfig.DefaultOrganizationID holds the default value on creation for the organization_id field.
 	employeeconfig.DefaultOrganizationID = employeeconfigDescOrganizationID.Default.(uint64)
 	labelMixin := schema.Label{}.Mixin()
+	labelMixinHooks2 := labelMixin[2].Hooks()
+	label.Hooks[0] = labelMixinHooks2[0]
+	labelMixinInters2 := labelMixin[2].Interceptors()
+	label.Interceptors[0] = labelMixinInters2[0]
 	labelMixinFields0 := labelMixin[0].Fields()
 	_ = labelMixinFields0
 	labelMixinFields1 := labelMixin[1].Fields()
@@ -935,6 +939,10 @@ func init() {
 	// labellog.DefaultOrganizationID holds the default value on creation for the organization_id field.
 	labellog.DefaultOrganizationID = labellogDescOrganizationID.Default.(uint64)
 	labelrelationshipMixin := schema.LabelRelationship{}.Mixin()
+	labelrelationshipMixinHooks2 := labelrelationshipMixin[2].Hooks()
+	labelrelationship.Hooks[0] = labelrelationshipMixinHooks2[0]
+	labelrelationshipMixinInters2 := labelrelationshipMixin[2].Interceptors()
+	labelrelationship.Interceptors[0] = labelrelationshipMixinInters2[0]
 	labelrelationshipMixinFields0 := labelrelationshipMixin[0].Fields()
 	_ = labelrelationshipMixinFields0
 	labelrelationshipMixinFields1 := labelrelationshipMixin[1].Fields()

+ 2 - 0
ent/schema/label.go

@@ -8,6 +8,7 @@ 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 {
@@ -41,6 +42,7 @@ func (Label) Mixin() []ent.Mixin {
 	return []ent.Mixin{
 		mixins.IDMixin{},
 		mixins.StatusMixin{},
+		localmixin.SoftDeleteMixin{},
 	}
 }
 

+ 2 - 0
ent/schema/label_relationship.go

@@ -8,6 +8,7 @@ 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 {
@@ -32,6 +33,7 @@ func (LabelRelationship) Mixin() []ent.Mixin {
 	return []ent.Mixin{
 		mixins.IDMixin{},
 		mixins.StatusMixin{},
+		localmixin.SoftDeleteMixin{},
 	}
 }
 

+ 48 - 0
ent/set_not_nil.go

@@ -4760,6 +4760,30 @@ func (l *LabelCreate) SetNotNilStatus(value *uint8) *LabelCreate {
 }
 
 // set field if value's pointer is not nil.
+func (l *LabelUpdate) SetNotNilDeletedAt(value *time.Time) *LabelUpdate {
+	if value != nil {
+		return l.SetDeletedAt(*value)
+	}
+	return l
+}
+
+// set field if value's pointer is not nil.
+func (l *LabelUpdateOne) SetNotNilDeletedAt(value *time.Time) *LabelUpdateOne {
+	if value != nil {
+		return l.SetDeletedAt(*value)
+	}
+	return l
+}
+
+// set field if value's pointer is not nil.
+func (l *LabelCreate) SetNotNilDeletedAt(value *time.Time) *LabelCreate {
+	if value != nil {
+		return l.SetDeletedAt(*value)
+	}
+	return l
+}
+
+// set field if value's pointer is not nil.
 func (l *LabelUpdate) SetNotNilType(value *int) *LabelUpdate {
 	if value != nil {
 		return l.SetType(*value)
@@ -5072,6 +5096,30 @@ func (lr *LabelRelationshipCreate) SetNotNilStatus(value *uint8) *LabelRelations
 }
 
 // set field if value's pointer is not nil.
+func (lr *LabelRelationshipUpdate) SetNotNilDeletedAt(value *time.Time) *LabelRelationshipUpdate {
+	if value != nil {
+		return lr.SetDeletedAt(*value)
+	}
+	return lr
+}
+
+// set field if value's pointer is not nil.
+func (lr *LabelRelationshipUpdateOne) SetNotNilDeletedAt(value *time.Time) *LabelRelationshipUpdateOne {
+	if value != nil {
+		return lr.SetDeletedAt(*value)
+	}
+	return lr
+}
+
+// set field if value's pointer is not nil.
+func (lr *LabelRelationshipCreate) SetNotNilDeletedAt(value *time.Time) *LabelRelationshipCreate {
+	if value != nil {
+		return lr.SetDeletedAt(*value)
+	}
+	return lr
+}
+
+// set field if value's pointer is not nil.
 func (lr *LabelRelationshipUpdate) SetNotNilLabelID(value *uint64) *LabelRelationshipUpdate {
 	if value != nil {
 		return lr.SetLabelID(*value)

+ 44 - 0
internal/handler/Wx/change_organization_handler.go

@@ -0,0 +1,44 @@
+package Wx
+
+import (
+	"net/http"
+
+	"github.com/zeromicro/go-zero/rest/httpx"
+
+	"wechat-api/internal/logic/Wx"
+	"wechat-api/internal/svc"
+	"wechat-api/internal/types"
+)
+
+// swagger:route post /wx/changeOrganization Wx ChangeOrganization
+//
+// Change wx organization | 切换租户
+//
+// Change wx organization | 切换租户
+//
+// Parameters:
+//  + name: body
+//    require: true
+//    in: body
+//    type: WxInfo
+//
+// Responses:
+//  200: BaseMsgResp
+
+func ChangeOrganizationHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
+	return func(w http.ResponseWriter, r *http.Request) {
+		var req types.WxInfo
+		if err := httpx.Parse(r, &req, true); err != nil {
+			httpx.ErrorCtx(r.Context(), w, err)
+			return
+		}
+
+		l := Wx.NewChangeOrganizationLogic(r.Context(), svcCtx)
+		resp, err := l.ChangeOrganization(&req)
+		if err != nil {
+			httpx.ErrorCtx(r.Context(), w, err)
+		} else {
+			httpx.OkJsonCtx(r.Context(), w, resp)
+		}
+	}
+}

+ 5 - 0
internal/handler/routes.go

@@ -130,6 +130,11 @@ func RegisterHandlers(server *rest.Server, serverCtx *svc.ServiceContext) {
 				},
 				{
 					Method:  http.MethodPost,
+					Path:    "/wx/changeOrganization",
+					Handler: Wx.ChangeOrganizationHandler(serverCtx),
+				},
+				{
+					Method:  http.MethodPost,
 					Path:    "/wx/updateBlockAndAllowList",
 					Handler: Wx.UpdateBlockAndAllowListHandler(serverCtx),
 				},

+ 2 - 1
internal/logic/WorkPhone/wx_refresh_logic.go

@@ -24,7 +24,8 @@ func NewWxRefreshLogic(ctx context.Context, svcCtx *svc.ServiceContext) *WxRefre
 }
 
 func (l *WxRefreshLogic) WxRefresh() (resp *types.BaseMsgResp, err error) {
-	wechat.SyncAllWx(l.svcCtx)
+	syncWx := wechat.SyncWx{Ctx: l.ctx, DB: l.svcCtx.DB}
+	syncWx.SyncAll()
 
 	return &types.BaseMsgResp{Msg: errormsg.Success}, nil
 }

+ 62 - 0
internal/logic/Wx/change_organization_logic.go

@@ -0,0 +1,62 @@
+package Wx
+
+import (
+	"context"
+	"github.com/suyuan32/simple-admin-common/msg/errormsg"
+	"github.com/zeromicro/go-zero/core/errorx"
+	"wechat-api/ent/wx"
+	"wechat-api/internal/service/wechat"
+
+	"wechat-api/internal/svc"
+	"wechat-api/internal/types"
+
+	"github.com/zeromicro/go-zero/core/logx"
+)
+
+type ChangeOrganizationLogic struct {
+	logx.Logger
+	ctx    context.Context
+	svcCtx *svc.ServiceContext
+}
+
+func NewChangeOrganizationLogic(ctx context.Context, svcCtx *svc.ServiceContext) *ChangeOrganizationLogic {
+	return &ChangeOrganizationLogic{
+		Logger: logx.WithContext(ctx),
+		ctx:    ctx,
+		svcCtx: svcCtx}
+}
+
+func (l *ChangeOrganizationLogic) ChangeOrganization(req *types.WxInfo) (resp *types.BaseMsgResp, err error) {
+	isAdmin := l.ctx.Value("isAdmin").(bool)
+	if !isAdmin {
+		return nil, errorx.NewDefaultError("仅管理员可调整租户")
+	}
+
+	tx, err := l.svcCtx.DB.Tx(l.ctx)
+	if err != nil {
+		return nil, err
+	}
+	defer tx.Rollback()
+
+	change := wechat.WxSafeChange{Ctx: l.ctx, Tx: tx, WxId: *req.Wxid, OrganizationId: *req.OrganizationId}
+	err = change.KeepAllSafe()
+	if err != nil {
+		_ = tx.Rollback()
+		return nil, err
+	}
+	_, err = tx.Wx.Update().
+		Where(wx.WxidEQ(*req.Wxid)).
+		SetNotNilOrganizationID(req.OrganizationId).
+		Save(l.ctx)
+	if err != nil {
+		_ = tx.Rollback()
+		return nil, err
+	}
+
+	err = tx.Commit()
+	if err != nil {
+		return nil, err
+	}
+
+	return &types.BaseMsgResp{Msg: errormsg.UpdateSuccess}, nil
+}

+ 4 - 2
internal/logic/contact/delete_contact_logic.go

@@ -27,8 +27,10 @@ func NewDeleteContactLogic(ctx context.Context, svcCtx *svc.ServiceContext) *Del
 }
 
 func (l *DeleteContactLogic) DeleteContact(req *types.IDsReq) (*types.BaseMsgResp, error) {
-	organizationId := l.ctx.Value("organizationId").(uint64)
-	_, err := l.svcCtx.DB.Contact.Delete().Where(contact.IDIn(req.Ids...), contact.OrganizationIDEQ(organizationId)).Exec(l.ctx)
+	//organizationId := l.ctx.Value("organizationId").(uint64)
+	_, err := l.svcCtx.DB.Contact.Delete().Where(
+		contact.IDIn(req.Ids...),
+	).Exec(l.ctx)
 
 	if err != nil {
 		return nil, dberrorhandler.DefaultEntError(l.Logger, err, req)

+ 12 - 2
internal/logic/contact/get_contact_by_id_logic.go

@@ -6,6 +6,7 @@ import (
 	"wechat-api/ent/contact"
 	"wechat-api/ent/contactfieldtemplate"
 	"wechat-api/ent/custom_types"
+	"wechat-api/ent/wx"
 	"wechat-api/internal/svc"
 	"wechat-api/internal/types"
 	"wechat-api/internal/utils/dberrorhandler"
@@ -34,8 +35,7 @@ func (l *GetContactByIdLogic) GetContactById(req *types.IDReq) (*types.ContactIn
 	organizationId := l.ctx.Value("organizationId").(uint64)
 	data, err := l.svcCtx.DB.Contact.Query().
 		Where(
-			contact.IDEQ(req.Id),                   // Filter by ID
-			contact.OrganizationID(organizationId), // Additional filter by organizationId
+			contact.IDEQ(req.Id),
 		).WithContactFields(func(query *ent.ContactFieldQuery) {
 		query.WithFieldContact()
 	}).
@@ -44,6 +44,16 @@ func (l *GetContactByIdLogic) GetContactById(req *types.IDReq) (*types.ContactIn
 		return nil, dberrorhandler.DefaultEntError(l.Logger, err, req)
 	}
 
+	wxinfo, err := l.svcCtx.DB.Wx.Query().
+		Where(
+			wx.WxidEQ(data.WxWxid),
+			wx.OrganizationIDEQ(organizationId),
+		).
+		Only(l.ctx)
+	if err != nil || wxinfo == nil {
+		return nil, err
+	}
+
 	var custom_field []types.ContactFieldTemplate
 	field_template, _ := l.svcCtx.DB.ContactFieldTemplate.Query().
 		Where(

+ 25 - 3
internal/logic/contact/get_contact_list_logic.go

@@ -53,11 +53,33 @@ func convertLabelToLabelInfo(label *ent.Label) types.LabelInfo {
 
 func (l *GetContactListLogic) GetContactList(req *types.ContactListReq) (*types.ContactListResp, error) {
 	organizationId := l.ctx.Value("organizationId").(uint64)
-	isAdmin := l.ctx.Value("isAdmin").(bool)
+	//isAdmin := l.ctx.Value("isAdmin").(bool)
+	wxslist := make([]string, 0)
+
 	var predicates []predicate.Contact
-	if req.WxWxid == nil || (req.WxWxid != nil && !isAdmin) {
-		predicates = append(predicates, contact.OrganizationIDEQ(organizationId))
+	if req.WxWxid == nil {
+		wxsInfo, err := l.svcCtx.DB.Wx.Query().
+			Where(
+				wx.OrganizationIDEQ(organizationId),
+			).All(l.ctx)
+		if err != nil {
+			return nil, dberrorhandler.DefaultEntError(l.Logger, err, req)
+		}
+		for _, w := range wxsInfo {
+			wxslist = append(wxslist, w.Wxid)
+		}
+	} else {
+		wxInfo, err := l.svcCtx.DB.Wx.Query().
+			Where(
+				wx.WxidEQ(*req.WxWxid),
+				wx.OrganizationIDEQ(organizationId),
+			).Only(l.ctx)
+		if err != nil {
+			return nil, dberrorhandler.DefaultEntError(l.Logger, err, req)
+		}
+		wxslist = append(wxslist, wxInfo.Wxid)
 	}
+	predicates = append(predicates, contact.WxWxidIn(wxslist...))
 	if req.Status != nil {
 		predicates = append(predicates, contact.StatusEQ(*req.Status))
 	}

+ 1 - 3
internal/logic/contact/update_contact_logic.go

@@ -3,7 +3,6 @@ package contact
 import (
 	"context"
 	"wechat-api/ent"
-	"wechat-api/ent/contact"
 	"wechat-api/ent/contactfield"
 	"wechat-api/internal/svc"
 	"wechat-api/internal/types"
@@ -32,13 +31,12 @@ func (l *UpdateContactLogic) UpdateContact(req *types.ContactInfo) (*types.BaseM
 	if err != nil {
 		return nil, err
 	}
-	organizationId := l.ctx.Value("organizationId").(uint64)
+	//organizationId := l.ctx.Value("organizationId").(uint64)
 	cage := 0
 	if req.Cage != nil && *req.Cage > 0 {
 		cage = *req.Cage
 	}
 	err = tx.Contact.UpdateOneID(*req.Id).
-		Where(contact.OrganizationID(organizationId)).
 		SetNotNilStatus(req.Status).
 		SetNotNilWxWxid(req.WxWxid).
 		SetNotNilType(req.Type).

+ 2 - 3
internal/logic/label/delete_label_logic.go

@@ -36,10 +36,9 @@ func (l *DeleteLabelLogic) DeleteLabel(req *types.IDsReq) (*types.BaseMsgResp, e
 		Where(
 			labelrelationship.HasLabelsWith(
 				label.IDIn(req.Ids...),
-			),                                                // Filter by ID
-			labelrelationship.OrganizationID(organizationId), // Additional filter by organizationId
+				label.OrganizationIDEQ(organizationId),
+			),
 			labelrelationship.HasContactsWith(
-				contact.OrganizationIDEQ(organizationId),
 				contact.DeletedAtIsNil(),
 			),
 		).

+ 4 - 1
internal/logic/label_tagging/delete_label_tagging_logic.go

@@ -27,7 +27,10 @@ func NewDeleteLabelTaggingLogic(ctx context.Context, svcCtx *svc.ServiceContext)
 
 func (l *DeleteLabelTaggingLogic) DeleteLabelTagging(req *types.IDsReq) (resp *types.BaseMsgResp, err error) {
 	organizationId := l.ctx.Value("organizationId").(uint64)
-	_, err = l.svcCtx.DB.LabelTagging.Delete().Where(labeltagging.IDIn(req.Ids...), labeltagging.OrganizationID(organizationId)).Exec(l.ctx)
+	_, err = l.svcCtx.DB.LabelTagging.Delete().Where(
+		labeltagging.IDIn(req.Ids...),
+		labeltagging.OrganizationID(organizationId),
+	).Exec(l.ctx)
 
 	if err != nil {
 		return nil, dberrorhandler.DefaultEntError(l.Logger, err, req)

+ 30 - 35
internal/service/wechat/sync_wx.go

@@ -9,11 +9,15 @@ import (
 	"time"
 	"wechat-api/ent"
 	"wechat-api/ent/wx"
-	"wechat-api/internal/svc"
 	"wechat-api/internal/types"
 )
 
-func SyncAllWx(svcCtx *svc.ServiceContext) {
+type SyncWx struct {
+	Ctx context.Context
+	DB  *ent.Client
+}
+
+func (s *SyncWx) SyncAll() {
 	// 获取微信列表
 	var result types.WorkPhoneGetWeChatsResp
 	client := req.C().DevMode()
@@ -35,19 +39,20 @@ func SyncAllWx(svcCtx *svc.ServiceContext) {
 		if account.Wechatid == nil || *account.Wechatid == "" {
 			continue
 		}
-		wxinfo, err := svcCtx.DB.Wx.Query().
+		wxinfo, err := s.DB.Wx.Query().
 			Where(
 				wx.And(
 					wx.WxidEQ(*account.Wechatid),
 					wx.CtypeEQ(1),
 				),
 			).
-			Only(context.TODO())
+			Only(s.Ctx)
 
 		if err != nil && !ent.IsNotFound(err) {
 			logx.Error("syncWx: ", err)
 			return
 		}
+
 		var status uint8
 		logx.Info(fmt.Printf("*account.Isonline: %d\n", *account.Isonline))
 		if *account.Isonline == 0 {
@@ -57,9 +62,20 @@ func SyncAllWx(svcCtx *svc.ServiceContext) {
 		}
 
 		if wxinfo != nil {
+			tx, err := s.DB.Tx(s.Ctx)
+			if err != nil {
+				continue
+			}
+			defer tx.Rollback()
+			change := WxSafeChange{Ctx: s.Ctx, Tx: tx, WxId: wxinfo.Wxid, OrganizationId: wxinfo.OrganizationID}
+			err = change.KeepAllSafe()
+			if err != nil {
+				_ = tx.Rollback()
+				continue
+			}
 			logx.Info(fmt.Printf("wxinfo is not nil, account: %s\n", *account.Wechatid))
 			logx.Info(fmt.Printf("wxinfo is not nil, account: %s\n", *account.Wechatnick))
-			err = svcCtx.DB.Wx.UpdateOneID(wxinfo.ID).
+			err = tx.Wx.UpdateOneID(wxinfo.ID).
 				SetServerID(0).
 				SetPort(*account.Deviceid).
 				SetProcessID(strconv.FormatInt(account.Cid, 10)).
@@ -67,14 +83,20 @@ func SyncAllWx(svcCtx *svc.ServiceContext) {
 				SetNotNilNickname(account.Wechatnick).
 				SetNotNilHeadBig(account.Avatar).
 				SetStatus(status).
-				Exec(context.TODO())
+				Exec(s.Ctx)
+			if err != nil {
+				_ = tx.Rollback()
+				logx.Error("syncWx: ", err)
+				continue
+			}
+			err = tx.Commit()
 			if err != nil {
 				logx.Error("syncWx: ", err)
 				continue
 			}
 		} else {
 			logx.Error(fmt.Printf("wxinfo is nil, account: %+v\n", account))
-			_, err := svcCtx.DB.Wx.Create().
+			_, err := s.DB.Wx.Create().
 				SetServerID(0).
 				SetPort(*account.Deviceid).
 				SetProcessID(strconv.FormatInt(account.Cid, 10)).
@@ -84,38 +106,11 @@ func SyncAllWx(svcCtx *svc.ServiceContext) {
 				SetNotNilNickname(account.Wechatnick).
 				SetStatus(status).
 				SetAllowList([]string{}).SetBlockList([]string{}).SetGroupAllowList([]string{}).SetGroupBlockList([]string{}).
-				Save(context.TODO())
+				Save(s.Ctx)
 			if err != nil {
 				logx.Error("syncWx: ", err)
 				continue
 			}
 		}
-
-		//data := map[string]interface{}{
-		//	"MsgType": "TriggerFriendPushTask",
-		//	"Content": map[string]interface{}{
-		//		"WeChatId": *account.Wechatid,
-		//	},
-		//}
-		//jsonStr, err := json.Marshal(data)
-		//err = svcCtx.WechatWs["default"].SendMsg([]byte(jsonStr))
-		//if err != nil {
-		//	logx.Error("syncWx: ", err)
-		//	continue
-		//}
-		//
-		//dataChatroom := map[string]interface{}{
-		//	"MsgType": "TriggerChatroomPushTask",
-		//	"Content": map[string]interface{}{
-		//		"WeChatId": *account.Wechatid,
-		//		"Flag":     1,
-		//	},
-		//}
-		//jsonStrChatroom, err := json.Marshal(dataChatroom)
-		//err = svcCtx.WechatWs["default"].SendMsg([]byte(jsonStrChatroom))
-		//if err != nil {
-		//	logx.Error("syncWx: ", err)
-		//	continue
-		//}
 	}
 }

+ 259 - 0
internal/service/wechat/wx_safe_change.go

@@ -0,0 +1,259 @@
+package wechat
+
+import (
+	"context"
+	"github.com/zeromicro/go-zero/core/logx"
+	"wechat-api/ent"
+	"wechat-api/ent/agent"
+	"wechat-api/ent/contact"
+	"wechat-api/ent/label"
+	"wechat-api/ent/labelrelationship"
+	"wechat-api/ent/wx"
+)
+
+type WxSafeChange struct {
+	Ctx            context.Context
+	Tx             *ent.Tx
+	WxId           string
+	OrganizationId uint64
+}
+
+func (w *WxSafeChange) KeepAllSafe() error {
+	err := w.BlockListSafe()
+	if err != nil {
+		return err
+	}
+	err = w.AgentSafe()
+	if err != nil {
+		return err
+	}
+	err = w.LabelSafe()
+	if err != nil {
+		return err
+	}
+	return nil
+}
+
+func (w *WxSafeChange) BlockListSafe() error {
+	wxinfo, err := w.Tx.Wx.Query().
+		Where(
+			wx.Wxid(w.WxId),
+		).
+		Only(w.Ctx)
+	if err != nil {
+		if ent.IsNotFound(err) {
+			return nil
+		}
+		return err
+	}
+	bl := []string{}
+	if wxinfo == nil {
+		return nil
+	}
+
+	for _, l := range wxinfo.BlockList {
+		if l != "" && l != "ALL" {
+			bl = append(bl, l)
+		}
+	}
+	for _, l := range wxinfo.GroupBlockList {
+		if l != "" && l != "ALL" {
+			bl = append(bl, l)
+		}
+	}
+	for _, l := range wxinfo.AllowList {
+		if l != "" && l != "ALL" {
+			bl = append(bl, l)
+		}
+	}
+	for _, l := range wxinfo.GroupAllowList {
+		if l != "" && l != "ALL" {
+			bl = append(bl, l)
+		}
+	}
+
+	contactList, err := w.Tx.Contact.Query().
+		Where(
+			contact.WxWxidNEQ(w.WxId),
+			contact.WxidIn(bl...),
+		).All(w.Ctx)
+
+	if err != nil && !ent.IsNotFound(err) {
+		return err
+	}
+
+	if contactList != nil {
+		_, err = w.Tx.Wx.UpdateOneID(wxinfo.ID).
+			SetBlockList([]string{}).
+			SetGroupBlockList([]string{}).
+			SetAllowList([]string{"ALL"}).
+			SetGroupAllowList([]string{"ALL"}).
+			Save(w.Ctx)
+		if err != nil {
+			return err
+		}
+	}
+
+	return nil
+}
+
+func (w *WxSafeChange) AgentSafe() error {
+	wxinfo, err := w.Tx.Wx.Query().
+		Where(
+			wx.Wxid(w.WxId),
+			wx.HasAgentWith(
+				agent.DeletedAtIsNil(),
+				agent.OrganizationIDNEQ(w.OrganizationId),
+			),
+		).
+		WithAgent().
+		Only(w.Ctx)
+	if err != nil {
+		if ent.IsNotFound(err) {
+			return nil
+		}
+		return err
+	}
+	if wxinfo != nil && wxinfo.Edges.Agent != nil {
+		_, err = w.Tx.Wx.UpdateOneID(wxinfo.ID).
+			SetAgentID(0).
+			Save(w.Ctx)
+		if err != nil {
+			return err
+		}
+	}
+	return nil
+}
+
+func (w *WxSafeChange) LabelSafe() error {
+	wxinfo, err := w.Tx.Wx.Query().
+		Where(
+			wx.Wxid(w.WxId),
+		).
+		Only(w.Ctx)
+	if err != nil || wxinfo == nil {
+		return err
+	}
+
+	// 获取现有联系人的所有标签名称
+	contactLabelNames, err := w.Tx.Label.Query().
+		Where(
+			label.DeletedAtIsNil(),
+			label.HasLabelRelationshipsWith(
+				labelrelationship.DeletedAtIsNil(),
+				labelrelationship.HasContactsWith(
+					contact.WxWxidEQ(w.WxId),
+				),
+			),
+		).
+		Select(label.FieldName).
+		Strings(w.Ctx)
+
+	if err != nil {
+		if ent.IsNotFound(err) {
+			return nil
+		}
+		return err
+	}
+
+	newLabelNames, err := w.Tx.Label.Query().
+		Where(
+			label.DeletedAtIsNil(),
+			label.OrganizationIDEQ(w.OrganizationId),
+		).
+		Select(label.FieldName).
+		Strings(w.Ctx)
+
+	if err != nil && !ent.IsNotFound(err) {
+		return err
+	}
+
+	// 构建 newLabelNames 的 set
+	newLabelSet := make(map[string]struct{})
+	for _, name := range newLabelNames {
+		newLabelSet[name] = struct{}{}
+	}
+
+	// 找出 contactLabelNames 中 newLabelNames 没有的
+	var diffLabelNames []string
+	for _, name := range contactLabelNames {
+		if _, exists := newLabelSet[name]; !exists {
+			diffLabelNames = append(diffLabelNames, name)
+		}
+	}
+
+	if diffLabelNames != nil && len(diffLabelNames) > 0 {
+		// 创建新标签
+		for _, labelName := range diffLabelNames {
+			_, err = w.Tx.Label.Create().
+				SetName(labelName).
+				SetOrganizationID(w.OrganizationId).
+				SetConditions("{}").
+				Save(w.Ctx)
+			if err != nil {
+				return err
+			}
+		}
+	}
+
+	// 建立新的标签 id 映射关系
+	logx.Info("contactLabelNames", contactLabelNames)
+	logx.Info("diffLabelNames", diffLabelNames)
+	orgLabels, err := w.Tx.Label.Query().
+		Where(
+			label.DeletedAtIsNil(),
+			label.OrganizationIDEQ(w.OrganizationId),
+			label.NameIn(contactLabelNames...),
+		).
+		Select(label.FieldID, label.FieldName).
+		All(w.Ctx)
+	if err != nil {
+		return err
+	}
+	labelSet := make(map[string]uint64)
+	for _, l := range orgLabels {
+		logx.Info("l.Name", l.Name, l.ID)
+		logx.Info("l.ID", l.ID)
+		labelSet[l.Name] = l.ID
+	}
+
+	// 建立新的标签关系
+	labelRelationships, err := w.Tx.LabelRelationship.Query().
+		Where(
+			labelrelationship.DeletedAtIsNil(),
+			labelrelationship.HasContactsWith(
+				contact.WxWxidEQ(w.WxId),
+			),
+		).WithLabels().WithContacts().All(w.Ctx)
+	if err != nil {
+		return err
+	}
+
+	for _, relationship := range labelRelationships {
+		if relationship.Edges.Labels == nil {
+			continue
+		}
+		_, err = w.Tx.LabelRelationship.Create().
+			SetLabelID(labelSet[relationship.Edges.Labels.Name]).
+			SetContactID(relationship.Edges.Contacts.ID).
+			Save(w.Ctx)
+		if err != nil {
+			return err
+		}
+	}
+
+	// 删除旧的标签关系
+	_, err = w.Tx.LabelRelationship.Delete().
+		Where(
+			labelrelationship.DeletedAtIsNil(),
+			labelrelationship.HasLabelsWith(
+				label.OrganizationIDNEQ(wxinfo.OrganizationID)),
+			labelrelationship.HasContactsWith(
+				contact.WxWxidEQ(w.WxId),
+			),
+		).Exec(w.Ctx)
+	if err != nil {
+		return err
+	}
+	return nil
+}