ソースを参照

fix:增加whatsapp联系人接口

jimmyyem 1 ヶ月 前
コミット
bb9bb6c1dd
59 ファイル変更5472 行追加60 行削除
  1. 3 0
      desc/wechat/batch_msg.api
  2. 61 0
      desc/wechat/contact.api
  3. 22 0
      desc/wechat/label_relationship.api
  4. 1 0
      desc/wechat/whatsapp.api
  5. 13 2
      ent/batchmsg.go
  6. 10 0
      ent/batchmsg/batchmsg.go
  7. 45 0
      ent/batchmsg/where.go
  8. 85 0
      ent/batchmsg_create.go
  9. 54 0
      ent/batchmsg_update.go
  10. 134 2
      ent/contact.go
  11. 120 0
      ent/contact/contact.go
  12. 765 0
      ent/contact/where.go
  13. 840 0
      ent/contact_create.go
  14. 468 0
      ent/contact_update.go
  15. 12 1
      ent/label.go
  16. 10 0
      ent/label/label.go
  17. 45 0
      ent/label/where.go
  18. 85 0
      ent/label_create.go
  19. 54 0
      ent/label_update.go
  20. 12 1
      ent/labelrelationship.go
  21. 10 0
      ent/labelrelationship/labelrelationship.go
  22. 45 0
      ent/labelrelationship/where.go
  23. 85 0
      ent/labelrelationship_create.go
  24. 54 0
      ent/labelrelationship_update.go
  25. 19 4
      ent/migrate/schema.go
  26. 818 47
      ent/mutation.go
  27. 60 0
      ent/runtime/runtime.go
  28. 1 0
      ent/schema/batch_msg.go
  29. 12 0
      ent/schema/contact.go
  30. 1 0
      ent/schema/label.go
  31. 1 0
      ent/schema/label_relationship.go
  32. 360 0
      ent/set_not_nil.go
  33. 65 1
      hook/aliyun/whatsapp.go
  34. 44 0
      internal/handler/contact/create_whatsapp_contact_handler.go
  35. 44 0
      internal/handler/contact/delete_whatsapp_contact_handler.go
  36. 44 0
      internal/handler/contact/get_whatsapp_contact_handler.go
  37. 44 0
      internal/handler/contact/get_whatsapp_contact_list_handler.go
  38. 70 0
      internal/handler/contact/import_whatsapp_contact_handler.go
  39. 44 0
      internal/handler/contact/update_whatsapp_contact_handler.go
  40. 44 0
      internal/handler/label_relationship/set_whatsapp_contact_batch_label_handler.go
  41. 44 0
      internal/handler/label_relationship/set_whatsapp_contact_label_handler.go
  42. 40 0
      internal/handler/routes.go
  43. 1 0
      internal/logic/batch_msg/create_batch_msg_logic.go
  44. 1 0
      internal/logic/batch_msg/get_batch_msg_list_logic.go
  45. 56 0
      internal/logic/contact/create_whatsapp_contact_logic.go
  46. 41 0
      internal/logic/contact/delete_whatsapp_contact_logic.go
  47. 104 0
      internal/logic/contact/get_whatsapp_contact_list_logic.go
  48. 66 0
      internal/logic/contact/get_whatsapp_contact_logic.go
  49. 111 0
      internal/logic/contact/import_whatsapp_contact_logic.go
  50. 52 0
      internal/logic/contact/update_whatsapp_contact_logic.go
  51. 1 0
      internal/logic/label/create_label_logic.go
  52. 1 0
      internal/logic/label/get_label_batch_select_list_logic.go
  53. 1 0
      internal/logic/label/get_label_contacts_logic.go
  54. 1 0
      internal/logic/label/get_label_list_logic.go
  55. 1 0
      internal/logic/label/get_label_select_list_logic.go
  56. 97 0
      internal/logic/label_relationship/set_whatsapp_contact_batch_label_logic.go
  57. 96 0
      internal/logic/label_relationship/set_whatsapp_contact_label_logic.go
  58. 2 1
      internal/logic/whatsapp/list_whatsapp_template_logic.go
  59. 52 1
      internal/types/types.go

+ 3 - 0
desc/wechat/batch_msg.api

@@ -49,6 +49,9 @@ type (
 
 		// 标签列表
 		Type  *int32 `json:"type,optional"`
+
+		// 内容类型:1-微信 2-whatsapp
+		Ctype *uint64 `json:"ctype,optional"`
     }
 
     // The response data of batch msg list | BatchMsg列表数据

+ 61 - 0
desc/wechat/contact.api

@@ -63,6 +63,43 @@ type (
         Type  *int `json:"type,optional"`
         Ai *bool `json:"ai,optional"`
     }
+
+	ImportWhatsappContactReq {
+		File *string `form:"file,optional"`
+	}
+	WhatsappContactListReq {
+		PageInfo
+
+		// 标签ID列表
+		LabelIDs []uint64 `json:"labelIDs,optional"`
+
+		// 电话
+		Phone  *string `json:"phone,optional"`
+
+		// 名称
+		Name  *string `json:"name,optional"`
+	}
+	CreateWhatsappContactReq {
+		BaseIDInfo
+
+		// 国家区号
+		Cc  *string `json:"cc"`
+		Phone *string `json:"phone"`
+
+		// 备注名
+		Markname  *string `json:"markname,optional"`
+
+		Ctype *uint64 `json:"ctype,optional"`
+		Cname *string `json:"cname,optional"`
+		Csex *int `json:"csex,optional"`
+		Cage *int `json:"cage,optional"`
+		Carea *string `json:"carea,optional"`
+		Cmobile *string `json:"cmobile,optional"`
+		Cbirtyday *string `json:"cbirtyday,optional"`
+		Cbirtharea *string `json:"cbirtharea,optional"`
+		CidcardNo *string `json:"cidcardNo,optional"`
+		Ctitle *string `json:"ctitle,optional"`
+	}
 )
 
 @server(
@@ -97,4 +134,28 @@ service Wechat {
 
     @handler changeBlockList
     post /contact/changeBlockList (changeBlockListReq) returns (BaseMsgResp)
+
+	// 导入Whatsapp联系人
+	@handler importWhatsappContact
+	post /contact/importWhatsappContact (ImportWhatsappContactReq) returns (BaseDataInfo)
+
+	// Whatsapp联系人列表
+	@handler getWhatsappContactList
+	post /contact/getWhatsappContactList (WhatsappContactListReq) returns (ContactListResp)
+
+	// Whatsapp联系人创建
+	@handler createWhatsappContact
+	post /contact/createWhatsappContact (CreateWhatsappContactReq) returns (BaseMsgResp)
+
+	// Whatsapp联系人编辑
+	@handler updateWhatsappContact
+	post /contact/updateWhatsappContact (CreateWhatsappContactReq) returns (BaseMsgResp)
+
+	// Whatsapp联系人删除
+	@handler deleteWhatsappContact
+	post /contact/deleteWhatsappContact (IDsReq) returns (BaseMsgResp)
+
+	// Whatsapp联系人详情
+	@handler getWhatsappContact
+	post /contact/getWhatsappContact (IDReq) returns (ContactInfoResp)
 }

+ 22 - 0
desc/wechat/label_relationship.api

@@ -73,6 +73,17 @@ type (
 
         // 是否在黑名单中
         IsInBlockList *bool `json:"isInBlockList,optional"`
+
+		Ctype *uint64 `json:"ctype,optional"`
+		Cname *string `json:"cname,optional"`
+		Csex *int `json:"csex,optional"`
+		Cage *int `json:"cage,optional"`
+		Carea *string `json:"carea,optional"`
+		Cmobile *string `json:"cmobile,optional"`
+		Cbirtyday *string `json:"cbirtyday,optional"`
+		Cbirtharea *string `json:"cbirtharea,optional"`
+		CidcardNo *string `json:"cidcardNo,optional"`
+		Ctitle *string `json:"ctitle,optional"`
     }
     // The response data of label information | Label信息
     LabelInfo {
@@ -101,6 +112,9 @@ type (
 
         // Label Relationships | 标签关系
         LabelRelationships []LabelRelationshipInfo `json:"labelRelationships,optional"`
+
+		// 内容类型:1-微信 2-whatsapp
+		Ctype *uint64 `json:"ctype,optional"`
     }
     // The response data of label relationship information | LabelRelationship信息
     LabelRelationshipInfo {
@@ -213,4 +227,12 @@ service Wechat {
     // Get label relationship by ID | 通过ID获取LabelRelationship
     @handler getLabelRelationshipById
     post /label_relationship (IDReq) returns (LabelRelationshipInfoResp)
+
+	// 更新WhatsappContact的Label信息
+	@handler setWhatsappContactLabel
+	post /label_relationship/setWhatsappContactLabel (LabelRelationshipsInfo) returns (BaseMsgResp)
+
+	// 批量更新WhatsappContact的Label信息
+	@handler setWhatsappContactBatchLabel
+	post /label_relationship/setWhatsappContactBatchLabel (BatchLabelRelationshipsInfo) returns (BaseMsgResp)
 }

+ 1 - 0
desc/wechat/whatsapp.api

@@ -364,6 +364,7 @@ type (
 		AuditStatus string `json:"auditStatus,optional"`
 		TemplateType string `json:"templateType,optional"`
 		Code string `json:"code,optional"`
+		WaId string `json:"waId,optional"`
 	}
 	listTemplateResp {
 		Code int    `json:"code"`

+ 13 - 2
ent/batchmsg.go

@@ -53,7 +53,9 @@ type BatchMsg struct {
 	Type int32 `json:"type,omitempty"`
 	// organization_id | 租户ID
 	OrganizationID uint64 `json:"organization_id,omitempty"`
-	selectValues   sql.SelectValues
+	// 内容类型:1-微信 2-whatsapp
+	Ctype        uint64 `json:"ctype,omitempty"`
+	selectValues sql.SelectValues
 }
 
 // scanValues returns the types for scanning values from sql.Rows.
@@ -61,7 +63,7 @@ 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, batchmsg.FieldType, batchmsg.FieldOrganizationID:
+		case batchmsg.FieldID, batchmsg.FieldStatus, batchmsg.FieldTotal, batchmsg.FieldSuccess, batchmsg.FieldFail, batchmsg.FieldType, batchmsg.FieldOrganizationID, batchmsg.FieldCtype:
 			values[i] = new(sql.NullInt64)
 		case batchmsg.FieldBatchNo, batchmsg.FieldTaskName, batchmsg.FieldFromwxid, batchmsg.FieldMsg, batchmsg.FieldTag, batchmsg.FieldTagids:
 			values[i] = new(sql.NullString)
@@ -196,6 +198,12 @@ func (bm *BatchMsg) assignValues(columns []string, values []any) error {
 			} else if value.Valid {
 				bm.OrganizationID = uint64(value.Int64)
 			}
+		case batchmsg.FieldCtype:
+			if value, ok := values[i].(*sql.NullInt64); !ok {
+				return fmt.Errorf("unexpected type %T for field ctype", values[i])
+			} else if value.Valid {
+				bm.Ctype = uint64(value.Int64)
+			}
 		default:
 			bm.selectValues.Set(columns[i], values[i])
 		}
@@ -285,6 +293,9 @@ func (bm *BatchMsg) String() string {
 	builder.WriteString(", ")
 	builder.WriteString("organization_id=")
 	builder.WriteString(fmt.Sprintf("%v", bm.OrganizationID))
+	builder.WriteString(", ")
+	builder.WriteString("ctype=")
+	builder.WriteString(fmt.Sprintf("%v", bm.Ctype))
 	builder.WriteByte(')')
 	return builder.String()
 }

+ 10 - 0
ent/batchmsg/batchmsg.go

@@ -50,6 +50,8 @@ const (
 	FieldType = "type"
 	// FieldOrganizationID holds the string denoting the organization_id field in the database.
 	FieldOrganizationID = "organization_id"
+	// FieldCtype holds the string denoting the ctype field in the database.
+	FieldCtype = "ctype"
 	// Table holds the table name of the batchmsg in the database.
 	Table = "batch_msg"
 )
@@ -75,6 +77,7 @@ var Columns = []string{
 	FieldSendTime,
 	FieldType,
 	FieldOrganizationID,
+	FieldCtype,
 }
 
 // ValidColumn reports if the column name is valid (part of the table columns).
@@ -105,6 +108,8 @@ var (
 	DefaultTaskName string
 	// OrganizationIDValidator is a validator for the "organization_id" field. It is called by the builders before save.
 	OrganizationIDValidator func(uint64) error
+	// DefaultCtype holds the default value on creation for the "ctype" field.
+	DefaultCtype uint64
 )
 
 // OrderOption defines the ordering options for the BatchMsg queries.
@@ -204,3 +209,8 @@ func ByType(opts ...sql.OrderTermOption) OrderOption {
 func ByOrganizationID(opts ...sql.OrderTermOption) OrderOption {
 	return sql.OrderByField(FieldOrganizationID, opts...).ToFunc()
 }
+
+// ByCtype orders the results by the ctype field.
+func ByCtype(opts ...sql.OrderTermOption) OrderOption {
+	return sql.OrderByField(FieldCtype, opts...).ToFunc()
+}

+ 45 - 0
ent/batchmsg/where.go

@@ -144,6 +144,11 @@ func OrganizationID(v uint64) predicate.BatchMsg {
 	return predicate.BatchMsg(sql.FieldEQ(FieldOrganizationID, v))
 }
 
+// Ctype applies equality check predicate on the "ctype" field. It's identical to CtypeEQ.
+func Ctype(v uint64) predicate.BatchMsg {
+	return predicate.BatchMsg(sql.FieldEQ(FieldCtype, 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))
@@ -1164,6 +1169,46 @@ func OrganizationIDLTE(v uint64) predicate.BatchMsg {
 	return predicate.BatchMsg(sql.FieldLTE(FieldOrganizationID, v))
 }
 
+// CtypeEQ applies the EQ predicate on the "ctype" field.
+func CtypeEQ(v uint64) predicate.BatchMsg {
+	return predicate.BatchMsg(sql.FieldEQ(FieldCtype, v))
+}
+
+// CtypeNEQ applies the NEQ predicate on the "ctype" field.
+func CtypeNEQ(v uint64) predicate.BatchMsg {
+	return predicate.BatchMsg(sql.FieldNEQ(FieldCtype, v))
+}
+
+// CtypeIn applies the In predicate on the "ctype" field.
+func CtypeIn(vs ...uint64) predicate.BatchMsg {
+	return predicate.BatchMsg(sql.FieldIn(FieldCtype, vs...))
+}
+
+// CtypeNotIn applies the NotIn predicate on the "ctype" field.
+func CtypeNotIn(vs ...uint64) predicate.BatchMsg {
+	return predicate.BatchMsg(sql.FieldNotIn(FieldCtype, vs...))
+}
+
+// CtypeGT applies the GT predicate on the "ctype" field.
+func CtypeGT(v uint64) predicate.BatchMsg {
+	return predicate.BatchMsg(sql.FieldGT(FieldCtype, v))
+}
+
+// CtypeGTE applies the GTE predicate on the "ctype" field.
+func CtypeGTE(v uint64) predicate.BatchMsg {
+	return predicate.BatchMsg(sql.FieldGTE(FieldCtype, v))
+}
+
+// CtypeLT applies the LT predicate on the "ctype" field.
+func CtypeLT(v uint64) predicate.BatchMsg {
+	return predicate.BatchMsg(sql.FieldLT(FieldCtype, v))
+}
+
+// CtypeLTE applies the LTE predicate on the "ctype" field.
+func CtypeLTE(v uint64) predicate.BatchMsg {
+	return predicate.BatchMsg(sql.FieldLTE(FieldCtype, v))
+}
+
 // And groups predicates with the AND operator between them.
 func And(predicates ...predicate.BatchMsg) predicate.BatchMsg {
 	return predicate.BatchMsg(sql.AndPredicates(predicates...))

+ 85 - 0
ent/batchmsg_create.go

@@ -266,6 +266,20 @@ func (bmc *BatchMsgCreate) SetOrganizationID(u uint64) *BatchMsgCreate {
 	return bmc
 }
 
+// SetCtype sets the "ctype" field.
+func (bmc *BatchMsgCreate) SetCtype(u uint64) *BatchMsgCreate {
+	bmc.mutation.SetCtype(u)
+	return bmc
+}
+
+// SetNillableCtype sets the "ctype" field if the given value is not nil.
+func (bmc *BatchMsgCreate) SetNillableCtype(u *uint64) *BatchMsgCreate {
+	if u != nil {
+		bmc.SetCtype(*u)
+	}
+	return bmc
+}
+
 // SetID sets the "id" field.
 func (bmc *BatchMsgCreate) SetID(u uint64) *BatchMsgCreate {
 	bmc.mutation.SetID(u)
@@ -327,6 +341,10 @@ func (bmc *BatchMsgCreate) defaults() error {
 		v := batchmsg.DefaultTaskName
 		bmc.mutation.SetTaskName(v)
 	}
+	if _, ok := bmc.mutation.Ctype(); !ok {
+		v := batchmsg.DefaultCtype
+		bmc.mutation.SetCtype(v)
+	}
 	return nil
 }
 
@@ -346,6 +364,9 @@ func (bmc *BatchMsgCreate) check() error {
 			return &ValidationError{Name: "organization_id", err: fmt.Errorf(`ent: validator failed for field "BatchMsg.organization_id": %w`, err)}
 		}
 	}
+	if _, ok := bmc.mutation.Ctype(); !ok {
+		return &ValidationError{Name: "ctype", err: errors.New(`ent: missing required field "BatchMsg.ctype"`)}
+	}
 	return nil
 }
 
@@ -451,6 +472,10 @@ func (bmc *BatchMsgCreate) createSpec() (*BatchMsg, *sqlgraph.CreateSpec) {
 		_spec.SetField(batchmsg.FieldOrganizationID, field.TypeUint64, value)
 		_node.OrganizationID = value
 	}
+	if value, ok := bmc.mutation.Ctype(); ok {
+		_spec.SetField(batchmsg.FieldCtype, field.TypeUint64, value)
+		_node.Ctype = value
+	}
 	return _node, _spec
 }
 
@@ -833,6 +858,24 @@ func (u *BatchMsgUpsert) AddOrganizationID(v uint64) *BatchMsgUpsert {
 	return u
 }
 
+// SetCtype sets the "ctype" field.
+func (u *BatchMsgUpsert) SetCtype(v uint64) *BatchMsgUpsert {
+	u.Set(batchmsg.FieldCtype, v)
+	return u
+}
+
+// UpdateCtype sets the "ctype" field to the value that was provided on create.
+func (u *BatchMsgUpsert) UpdateCtype() *BatchMsgUpsert {
+	u.SetExcluded(batchmsg.FieldCtype)
+	return u
+}
+
+// AddCtype adds v to the "ctype" field.
+func (u *BatchMsgUpsert) AddCtype(v uint64) *BatchMsgUpsert {
+	u.Add(batchmsg.FieldCtype, v)
+	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:
 //
@@ -1269,6 +1312,27 @@ func (u *BatchMsgUpsertOne) UpdateOrganizationID() *BatchMsgUpsertOne {
 	})
 }
 
+// SetCtype sets the "ctype" field.
+func (u *BatchMsgUpsertOne) SetCtype(v uint64) *BatchMsgUpsertOne {
+	return u.Update(func(s *BatchMsgUpsert) {
+		s.SetCtype(v)
+	})
+}
+
+// AddCtype adds v to the "ctype" field.
+func (u *BatchMsgUpsertOne) AddCtype(v uint64) *BatchMsgUpsertOne {
+	return u.Update(func(s *BatchMsgUpsert) {
+		s.AddCtype(v)
+	})
+}
+
+// UpdateCtype sets the "ctype" field to the value that was provided on create.
+func (u *BatchMsgUpsertOne) UpdateCtype() *BatchMsgUpsertOne {
+	return u.Update(func(s *BatchMsgUpsert) {
+		s.UpdateCtype()
+	})
+}
+
 // Exec executes the query.
 func (u *BatchMsgUpsertOne) Exec(ctx context.Context) error {
 	if len(u.create.conflict) == 0 {
@@ -1871,6 +1935,27 @@ func (u *BatchMsgUpsertBulk) UpdateOrganizationID() *BatchMsgUpsertBulk {
 	})
 }
 
+// SetCtype sets the "ctype" field.
+func (u *BatchMsgUpsertBulk) SetCtype(v uint64) *BatchMsgUpsertBulk {
+	return u.Update(func(s *BatchMsgUpsert) {
+		s.SetCtype(v)
+	})
+}
+
+// AddCtype adds v to the "ctype" field.
+func (u *BatchMsgUpsertBulk) AddCtype(v uint64) *BatchMsgUpsertBulk {
+	return u.Update(func(s *BatchMsgUpsert) {
+		s.AddCtype(v)
+	})
+}
+
+// UpdateCtype sets the "ctype" field to the value that was provided on create.
+func (u *BatchMsgUpsertBulk) UpdateCtype() *BatchMsgUpsertBulk {
+	return u.Update(func(s *BatchMsgUpsert) {
+		s.UpdateCtype()
+	})
+}
+
 // Exec executes the query.
 func (u *BatchMsgUpsertBulk) Exec(ctx context.Context) error {
 	if u.create.err != nil {

+ 54 - 0
ent/batchmsg_update.go

@@ -390,6 +390,27 @@ func (bmu *BatchMsgUpdate) AddOrganizationID(u int64) *BatchMsgUpdate {
 	return bmu
 }
 
+// SetCtype sets the "ctype" field.
+func (bmu *BatchMsgUpdate) SetCtype(u uint64) *BatchMsgUpdate {
+	bmu.mutation.ResetCtype()
+	bmu.mutation.SetCtype(u)
+	return bmu
+}
+
+// SetNillableCtype sets the "ctype" field if the given value is not nil.
+func (bmu *BatchMsgUpdate) SetNillableCtype(u *uint64) *BatchMsgUpdate {
+	if u != nil {
+		bmu.SetCtype(*u)
+	}
+	return bmu
+}
+
+// AddCtype adds u to the "ctype" field.
+func (bmu *BatchMsgUpdate) AddCtype(u int64) *BatchMsgUpdate {
+	bmu.mutation.AddCtype(u)
+	return bmu
+}
+
 // Mutation returns the BatchMsgMutation object of the builder.
 func (bmu *BatchMsgUpdate) Mutation() *BatchMsgMutation {
 	return bmu.mutation
@@ -573,6 +594,12 @@ func (bmu *BatchMsgUpdate) sqlSave(ctx context.Context) (n int, err error) {
 	if value, ok := bmu.mutation.AddedOrganizationID(); ok {
 		_spec.AddField(batchmsg.FieldOrganizationID, field.TypeUint64, value)
 	}
+	if value, ok := bmu.mutation.Ctype(); ok {
+		_spec.SetField(batchmsg.FieldCtype, field.TypeUint64, value)
+	}
+	if value, ok := bmu.mutation.AddedCtype(); ok {
+		_spec.AddField(batchmsg.FieldCtype, field.TypeUint64, value)
+	}
 	if n, err = sqlgraph.UpdateNodes(ctx, bmu.driver, _spec); err != nil {
 		if _, ok := err.(*sqlgraph.NotFoundError); ok {
 			err = &NotFoundError{batchmsg.Label}
@@ -955,6 +982,27 @@ func (bmuo *BatchMsgUpdateOne) AddOrganizationID(u int64) *BatchMsgUpdateOne {
 	return bmuo
 }
 
+// SetCtype sets the "ctype" field.
+func (bmuo *BatchMsgUpdateOne) SetCtype(u uint64) *BatchMsgUpdateOne {
+	bmuo.mutation.ResetCtype()
+	bmuo.mutation.SetCtype(u)
+	return bmuo
+}
+
+// SetNillableCtype sets the "ctype" field if the given value is not nil.
+func (bmuo *BatchMsgUpdateOne) SetNillableCtype(u *uint64) *BatchMsgUpdateOne {
+	if u != nil {
+		bmuo.SetCtype(*u)
+	}
+	return bmuo
+}
+
+// AddCtype adds u to the "ctype" field.
+func (bmuo *BatchMsgUpdateOne) AddCtype(u int64) *BatchMsgUpdateOne {
+	bmuo.mutation.AddCtype(u)
+	return bmuo
+}
+
 // Mutation returns the BatchMsgMutation object of the builder.
 func (bmuo *BatchMsgUpdateOne) Mutation() *BatchMsgMutation {
 	return bmuo.mutation
@@ -1168,6 +1216,12 @@ func (bmuo *BatchMsgUpdateOne) sqlSave(ctx context.Context) (_node *BatchMsg, er
 	if value, ok := bmuo.mutation.AddedOrganizationID(); ok {
 		_spec.AddField(batchmsg.FieldOrganizationID, field.TypeUint64, value)
 	}
+	if value, ok := bmuo.mutation.Ctype(); ok {
+		_spec.SetField(batchmsg.FieldCtype, field.TypeUint64, value)
+	}
+	if value, ok := bmuo.mutation.AddedCtype(); ok {
+		_spec.AddField(batchmsg.FieldCtype, field.TypeUint64, value)
+	}
 	_node = &BatchMsg{config: bmuo.config}
 	_spec.Assign = _node.assignValues
 	_spec.ScanValues = _node.scanValues

+ 134 - 2
ent/contact.go

@@ -57,6 +57,30 @@ type Contact struct {
 	V3 string `json:"v3,omitempty"`
 	// 机构 ID
 	OrganizationID uint64 `json:"organization_id,omitempty"`
+	// 内容类型:1-微信 2-whatsapp
+	Ctype uint64 `json:"ctype,omitempty"`
+	// 性别:1-男 2-女
+	Csex int `json:"csex,omitempty"`
+	// 年龄
+	Cage int `json:"cage,omitempty"`
+	// 姓名
+	Cname string `json:"cname,omitempty"`
+	// 地区
+	Carea string `json:"carea,omitempty"`
+	// 手机号
+	Cmobile string `json:"cmobile,omitempty"`
+	// 出生日期
+	Cbirthday string `json:"cbirthday,omitempty"`
+	// 出生地
+	Cbirtharea string `json:"cbirtharea,omitempty"`
+	// 身份证号
+	CidcardNo string `json:"cidcard_no,omitempty"`
+	// 称呼
+	Ctitle string `json:"ctitle,omitempty"`
+	// 国家区号
+	Cc string `json:"cc,omitempty"`
+	// 手机号
+	Phone string `json:"phone,omitempty"`
 	// Edges holds the relations/edges for other nodes in the graph.
 	// The values are being populated by the ContactQuery when eager-loading is set.
 	Edges        ContactEdges `json:"edges"`
@@ -97,9 +121,9 @@ func (*Contact) scanValues(columns []string) ([]any, error) {
 	values := make([]any, len(columns))
 	for i := range columns {
 		switch columns[i] {
-		case contact.FieldID, contact.FieldStatus, contact.FieldType, contact.FieldSex, contact.FieldDontseeit, contact.FieldDontseeme, contact.FieldOrganizationID:
+		case contact.FieldID, contact.FieldStatus, contact.FieldType, contact.FieldSex, contact.FieldDontseeit, contact.FieldDontseeme, contact.FieldOrganizationID, contact.FieldCtype, contact.FieldCsex, contact.FieldCage:
 			values[i] = new(sql.NullInt64)
-		case contact.FieldWxWxid, contact.FieldWxid, contact.FieldAccount, contact.FieldNickname, contact.FieldMarkname, contact.FieldHeadimg, contact.FieldStarrole, contact.FieldLag, contact.FieldGid, contact.FieldGname, contact.FieldV3:
+		case contact.FieldWxWxid, contact.FieldWxid, contact.FieldAccount, contact.FieldNickname, contact.FieldMarkname, contact.FieldHeadimg, contact.FieldStarrole, contact.FieldLag, contact.FieldGid, contact.FieldGname, contact.FieldV3, contact.FieldCname, contact.FieldCarea, contact.FieldCmobile, contact.FieldCbirthday, contact.FieldCbirtharea, contact.FieldCidcardNo, contact.FieldCtitle, contact.FieldCc, contact.FieldPhone:
 			values[i] = new(sql.NullString)
 		case contact.FieldCreatedAt, contact.FieldUpdatedAt, contact.FieldDeletedAt:
 			values[i] = new(sql.NullTime)
@@ -244,6 +268,78 @@ func (c *Contact) assignValues(columns []string, values []any) error {
 			} else if value.Valid {
 				c.OrganizationID = uint64(value.Int64)
 			}
+		case contact.FieldCtype:
+			if value, ok := values[i].(*sql.NullInt64); !ok {
+				return fmt.Errorf("unexpected type %T for field ctype", values[i])
+			} else if value.Valid {
+				c.Ctype = uint64(value.Int64)
+			}
+		case contact.FieldCsex:
+			if value, ok := values[i].(*sql.NullInt64); !ok {
+				return fmt.Errorf("unexpected type %T for field csex", values[i])
+			} else if value.Valid {
+				c.Csex = int(value.Int64)
+			}
+		case contact.FieldCage:
+			if value, ok := values[i].(*sql.NullInt64); !ok {
+				return fmt.Errorf("unexpected type %T for field cage", values[i])
+			} else if value.Valid {
+				c.Cage = int(value.Int64)
+			}
+		case contact.FieldCname:
+			if value, ok := values[i].(*sql.NullString); !ok {
+				return fmt.Errorf("unexpected type %T for field cname", values[i])
+			} else if value.Valid {
+				c.Cname = value.String
+			}
+		case contact.FieldCarea:
+			if value, ok := values[i].(*sql.NullString); !ok {
+				return fmt.Errorf("unexpected type %T for field carea", values[i])
+			} else if value.Valid {
+				c.Carea = value.String
+			}
+		case contact.FieldCmobile:
+			if value, ok := values[i].(*sql.NullString); !ok {
+				return fmt.Errorf("unexpected type %T for field cmobile", values[i])
+			} else if value.Valid {
+				c.Cmobile = value.String
+			}
+		case contact.FieldCbirthday:
+			if value, ok := values[i].(*sql.NullString); !ok {
+				return fmt.Errorf("unexpected type %T for field cbirthday", values[i])
+			} else if value.Valid {
+				c.Cbirthday = value.String
+			}
+		case contact.FieldCbirtharea:
+			if value, ok := values[i].(*sql.NullString); !ok {
+				return fmt.Errorf("unexpected type %T for field cbirtharea", values[i])
+			} else if value.Valid {
+				c.Cbirtharea = value.String
+			}
+		case contact.FieldCidcardNo:
+			if value, ok := values[i].(*sql.NullString); !ok {
+				return fmt.Errorf("unexpected type %T for field cidcard_no", values[i])
+			} else if value.Valid {
+				c.CidcardNo = value.String
+			}
+		case contact.FieldCtitle:
+			if value, ok := values[i].(*sql.NullString); !ok {
+				return fmt.Errorf("unexpected type %T for field ctitle", values[i])
+			} else if value.Valid {
+				c.Ctitle = value.String
+			}
+		case contact.FieldCc:
+			if value, ok := values[i].(*sql.NullString); !ok {
+				return fmt.Errorf("unexpected type %T for field cc", values[i])
+			} else if value.Valid {
+				c.Cc = value.String
+			}
+		case contact.FieldPhone:
+			if value, ok := values[i].(*sql.NullString); !ok {
+				return fmt.Errorf("unexpected type %T for field phone", values[i])
+			} else if value.Valid {
+				c.Phone = value.String
+			}
 		default:
 			c.selectValues.Set(columns[i], values[i])
 		}
@@ -349,6 +445,42 @@ func (c *Contact) String() string {
 	builder.WriteString(", ")
 	builder.WriteString("organization_id=")
 	builder.WriteString(fmt.Sprintf("%v", c.OrganizationID))
+	builder.WriteString(", ")
+	builder.WriteString("ctype=")
+	builder.WriteString(fmt.Sprintf("%v", c.Ctype))
+	builder.WriteString(", ")
+	builder.WriteString("csex=")
+	builder.WriteString(fmt.Sprintf("%v", c.Csex))
+	builder.WriteString(", ")
+	builder.WriteString("cage=")
+	builder.WriteString(fmt.Sprintf("%v", c.Cage))
+	builder.WriteString(", ")
+	builder.WriteString("cname=")
+	builder.WriteString(c.Cname)
+	builder.WriteString(", ")
+	builder.WriteString("carea=")
+	builder.WriteString(c.Carea)
+	builder.WriteString(", ")
+	builder.WriteString("cmobile=")
+	builder.WriteString(c.Cmobile)
+	builder.WriteString(", ")
+	builder.WriteString("cbirthday=")
+	builder.WriteString(c.Cbirthday)
+	builder.WriteString(", ")
+	builder.WriteString("cbirtharea=")
+	builder.WriteString(c.Cbirtharea)
+	builder.WriteString(", ")
+	builder.WriteString("cidcard_no=")
+	builder.WriteString(c.CidcardNo)
+	builder.WriteString(", ")
+	builder.WriteString("ctitle=")
+	builder.WriteString(c.Ctitle)
+	builder.WriteString(", ")
+	builder.WriteString("cc=")
+	builder.WriteString(c.Cc)
+	builder.WriteString(", ")
+	builder.WriteString("phone=")
+	builder.WriteString(c.Phone)
 	builder.WriteByte(')')
 	return builder.String()
 }

+ 120 - 0
ent/contact/contact.go

@@ -55,6 +55,30 @@ const (
 	FieldV3 = "v3"
 	// FieldOrganizationID holds the string denoting the organization_id field in the database.
 	FieldOrganizationID = "organization_id"
+	// FieldCtype holds the string denoting the ctype field in the database.
+	FieldCtype = "ctype"
+	// FieldCsex holds the string denoting the csex field in the database.
+	FieldCsex = "csex"
+	// FieldCage holds the string denoting the cage field in the database.
+	FieldCage = "cage"
+	// FieldCname holds the string denoting the cname field in the database.
+	FieldCname = "cname"
+	// FieldCarea holds the string denoting the carea field in the database.
+	FieldCarea = "carea"
+	// FieldCmobile holds the string denoting the cmobile field in the database.
+	FieldCmobile = "cmobile"
+	// FieldCbirthday holds the string denoting the cbirthday field in the database.
+	FieldCbirthday = "cbirthday"
+	// FieldCbirtharea holds the string denoting the cbirtharea field in the database.
+	FieldCbirtharea = "cbirtharea"
+	// FieldCidcardNo holds the string denoting the cidcard_no field in the database.
+	FieldCidcardNo = "cidcard_no"
+	// FieldCtitle holds the string denoting the ctitle field in the database.
+	FieldCtitle = "ctitle"
+	// FieldCc holds the string denoting the cc field in the database.
+	FieldCc = "cc"
+	// FieldPhone holds the string denoting the phone field in the database.
+	FieldPhone = "phone"
 	// EdgeContactRelationships holds the string denoting the contact_relationships edge name in mutations.
 	EdgeContactRelationships = "contact_relationships"
 	// EdgeContactMessages holds the string denoting the contact_messages edge name in mutations.
@@ -100,6 +124,18 @@ var Columns = []string{
 	FieldGname,
 	FieldV3,
 	FieldOrganizationID,
+	FieldCtype,
+	FieldCsex,
+	FieldCage,
+	FieldCname,
+	FieldCarea,
+	FieldCmobile,
+	FieldCbirthday,
+	FieldCbirtharea,
+	FieldCidcardNo,
+	FieldCtitle,
+	FieldCc,
+	FieldPhone,
 }
 
 // ValidColumn reports if the column name is valid (part of the table columns).
@@ -160,6 +196,30 @@ var (
 	DefaultV3 string
 	// DefaultOrganizationID holds the default value on creation for the "organization_id" field.
 	DefaultOrganizationID uint64
+	// DefaultCtype holds the default value on creation for the "ctype" field.
+	DefaultCtype uint64
+	// DefaultCsex holds the default value on creation for the "csex" field.
+	DefaultCsex int
+	// DefaultCage holds the default value on creation for the "cage" field.
+	DefaultCage int
+	// DefaultCname holds the default value on creation for the "cname" field.
+	DefaultCname string
+	// DefaultCarea holds the default value on creation for the "carea" field.
+	DefaultCarea string
+	// DefaultCmobile holds the default value on creation for the "cmobile" field.
+	DefaultCmobile string
+	// DefaultCbirthday holds the default value on creation for the "cbirthday" field.
+	DefaultCbirthday string
+	// DefaultCbirtharea holds the default value on creation for the "cbirtharea" field.
+	DefaultCbirtharea string
+	// DefaultCidcardNo holds the default value on creation for the "cidcard_no" field.
+	DefaultCidcardNo string
+	// DefaultCtitle holds the default value on creation for the "ctitle" field.
+	DefaultCtitle string
+	// DefaultCc holds the default value on creation for the "cc" field.
+	DefaultCc string
+	// DefaultPhone holds the default value on creation for the "phone" field.
+	DefaultPhone string
 )
 
 // OrderOption defines the ordering options for the Contact queries.
@@ -270,6 +330,66 @@ func ByOrganizationID(opts ...sql.OrderTermOption) OrderOption {
 	return sql.OrderByField(FieldOrganizationID, opts...).ToFunc()
 }
 
+// ByCtype orders the results by the ctype field.
+func ByCtype(opts ...sql.OrderTermOption) OrderOption {
+	return sql.OrderByField(FieldCtype, opts...).ToFunc()
+}
+
+// ByCsex orders the results by the csex field.
+func ByCsex(opts ...sql.OrderTermOption) OrderOption {
+	return sql.OrderByField(FieldCsex, opts...).ToFunc()
+}
+
+// ByCage orders the results by the cage field.
+func ByCage(opts ...sql.OrderTermOption) OrderOption {
+	return sql.OrderByField(FieldCage, opts...).ToFunc()
+}
+
+// ByCname orders the results by the cname field.
+func ByCname(opts ...sql.OrderTermOption) OrderOption {
+	return sql.OrderByField(FieldCname, opts...).ToFunc()
+}
+
+// ByCarea orders the results by the carea field.
+func ByCarea(opts ...sql.OrderTermOption) OrderOption {
+	return sql.OrderByField(FieldCarea, opts...).ToFunc()
+}
+
+// ByCmobile orders the results by the cmobile field.
+func ByCmobile(opts ...sql.OrderTermOption) OrderOption {
+	return sql.OrderByField(FieldCmobile, opts...).ToFunc()
+}
+
+// ByCbirthday orders the results by the cbirthday field.
+func ByCbirthday(opts ...sql.OrderTermOption) OrderOption {
+	return sql.OrderByField(FieldCbirthday, opts...).ToFunc()
+}
+
+// ByCbirtharea orders the results by the cbirtharea field.
+func ByCbirtharea(opts ...sql.OrderTermOption) OrderOption {
+	return sql.OrderByField(FieldCbirtharea, opts...).ToFunc()
+}
+
+// ByCidcardNo orders the results by the cidcard_no field.
+func ByCidcardNo(opts ...sql.OrderTermOption) OrderOption {
+	return sql.OrderByField(FieldCidcardNo, opts...).ToFunc()
+}
+
+// ByCtitle orders the results by the ctitle field.
+func ByCtitle(opts ...sql.OrderTermOption) OrderOption {
+	return sql.OrderByField(FieldCtitle, opts...).ToFunc()
+}
+
+// ByCc orders the results by the cc field.
+func ByCc(opts ...sql.OrderTermOption) OrderOption {
+	return sql.OrderByField(FieldCc, opts...).ToFunc()
+}
+
+// ByPhone orders the results by the phone field.
+func ByPhone(opts ...sql.OrderTermOption) OrderOption {
+	return sql.OrderByField(FieldPhone, opts...).ToFunc()
+}
+
 // ByContactRelationshipsCount orders the results by contact_relationships count.
 func ByContactRelationshipsCount(opts ...sql.OrderTermOption) OrderOption {
 	return func(s *sql.Selector) {

+ 765 - 0
ent/contact/where.go

@@ -155,6 +155,66 @@ func OrganizationID(v uint64) predicate.Contact {
 	return predicate.Contact(sql.FieldEQ(FieldOrganizationID, v))
 }
 
+// Ctype applies equality check predicate on the "ctype" field. It's identical to CtypeEQ.
+func Ctype(v uint64) predicate.Contact {
+	return predicate.Contact(sql.FieldEQ(FieldCtype, v))
+}
+
+// Csex applies equality check predicate on the "csex" field. It's identical to CsexEQ.
+func Csex(v int) predicate.Contact {
+	return predicate.Contact(sql.FieldEQ(FieldCsex, v))
+}
+
+// Cage applies equality check predicate on the "cage" field. It's identical to CageEQ.
+func Cage(v int) predicate.Contact {
+	return predicate.Contact(sql.FieldEQ(FieldCage, v))
+}
+
+// Cname applies equality check predicate on the "cname" field. It's identical to CnameEQ.
+func Cname(v string) predicate.Contact {
+	return predicate.Contact(sql.FieldEQ(FieldCname, v))
+}
+
+// Carea applies equality check predicate on the "carea" field. It's identical to CareaEQ.
+func Carea(v string) predicate.Contact {
+	return predicate.Contact(sql.FieldEQ(FieldCarea, v))
+}
+
+// Cmobile applies equality check predicate on the "cmobile" field. It's identical to CmobileEQ.
+func Cmobile(v string) predicate.Contact {
+	return predicate.Contact(sql.FieldEQ(FieldCmobile, v))
+}
+
+// Cbirthday applies equality check predicate on the "cbirthday" field. It's identical to CbirthdayEQ.
+func Cbirthday(v string) predicate.Contact {
+	return predicate.Contact(sql.FieldEQ(FieldCbirthday, v))
+}
+
+// Cbirtharea applies equality check predicate on the "cbirtharea" field. It's identical to CbirthareaEQ.
+func Cbirtharea(v string) predicate.Contact {
+	return predicate.Contact(sql.FieldEQ(FieldCbirtharea, v))
+}
+
+// CidcardNo applies equality check predicate on the "cidcard_no" field. It's identical to CidcardNoEQ.
+func CidcardNo(v string) predicate.Contact {
+	return predicate.Contact(sql.FieldEQ(FieldCidcardNo, v))
+}
+
+// Ctitle applies equality check predicate on the "ctitle" field. It's identical to CtitleEQ.
+func Ctitle(v string) predicate.Contact {
+	return predicate.Contact(sql.FieldEQ(FieldCtitle, v))
+}
+
+// Cc applies equality check predicate on the "cc" field. It's identical to CcEQ.
+func Cc(v string) predicate.Contact {
+	return predicate.Contact(sql.FieldEQ(FieldCc, v))
+}
+
+// Phone applies equality check predicate on the "phone" field. It's identical to PhoneEQ.
+func Phone(v string) predicate.Contact {
+	return predicate.Contact(sql.FieldEQ(FieldPhone, v))
+}
+
 // CreatedAtEQ applies the EQ predicate on the "created_at" field.
 func CreatedAtEQ(v time.Time) predicate.Contact {
 	return predicate.Contact(sql.FieldEQ(FieldCreatedAt, v))
@@ -1270,6 +1330,711 @@ func OrganizationIDNotNil() predicate.Contact {
 	return predicate.Contact(sql.FieldNotNull(FieldOrganizationID))
 }
 
+// CtypeEQ applies the EQ predicate on the "ctype" field.
+func CtypeEQ(v uint64) predicate.Contact {
+	return predicate.Contact(sql.FieldEQ(FieldCtype, v))
+}
+
+// CtypeNEQ applies the NEQ predicate on the "ctype" field.
+func CtypeNEQ(v uint64) predicate.Contact {
+	return predicate.Contact(sql.FieldNEQ(FieldCtype, v))
+}
+
+// CtypeIn applies the In predicate on the "ctype" field.
+func CtypeIn(vs ...uint64) predicate.Contact {
+	return predicate.Contact(sql.FieldIn(FieldCtype, vs...))
+}
+
+// CtypeNotIn applies the NotIn predicate on the "ctype" field.
+func CtypeNotIn(vs ...uint64) predicate.Contact {
+	return predicate.Contact(sql.FieldNotIn(FieldCtype, vs...))
+}
+
+// CtypeGT applies the GT predicate on the "ctype" field.
+func CtypeGT(v uint64) predicate.Contact {
+	return predicate.Contact(sql.FieldGT(FieldCtype, v))
+}
+
+// CtypeGTE applies the GTE predicate on the "ctype" field.
+func CtypeGTE(v uint64) predicate.Contact {
+	return predicate.Contact(sql.FieldGTE(FieldCtype, v))
+}
+
+// CtypeLT applies the LT predicate on the "ctype" field.
+func CtypeLT(v uint64) predicate.Contact {
+	return predicate.Contact(sql.FieldLT(FieldCtype, v))
+}
+
+// CtypeLTE applies the LTE predicate on the "ctype" field.
+func CtypeLTE(v uint64) predicate.Contact {
+	return predicate.Contact(sql.FieldLTE(FieldCtype, v))
+}
+
+// CsexEQ applies the EQ predicate on the "csex" field.
+func CsexEQ(v int) predicate.Contact {
+	return predicate.Contact(sql.FieldEQ(FieldCsex, v))
+}
+
+// CsexNEQ applies the NEQ predicate on the "csex" field.
+func CsexNEQ(v int) predicate.Contact {
+	return predicate.Contact(sql.FieldNEQ(FieldCsex, v))
+}
+
+// CsexIn applies the In predicate on the "csex" field.
+func CsexIn(vs ...int) predicate.Contact {
+	return predicate.Contact(sql.FieldIn(FieldCsex, vs...))
+}
+
+// CsexNotIn applies the NotIn predicate on the "csex" field.
+func CsexNotIn(vs ...int) predicate.Contact {
+	return predicate.Contact(sql.FieldNotIn(FieldCsex, vs...))
+}
+
+// CsexGT applies the GT predicate on the "csex" field.
+func CsexGT(v int) predicate.Contact {
+	return predicate.Contact(sql.FieldGT(FieldCsex, v))
+}
+
+// CsexGTE applies the GTE predicate on the "csex" field.
+func CsexGTE(v int) predicate.Contact {
+	return predicate.Contact(sql.FieldGTE(FieldCsex, v))
+}
+
+// CsexLT applies the LT predicate on the "csex" field.
+func CsexLT(v int) predicate.Contact {
+	return predicate.Contact(sql.FieldLT(FieldCsex, v))
+}
+
+// CsexLTE applies the LTE predicate on the "csex" field.
+func CsexLTE(v int) predicate.Contact {
+	return predicate.Contact(sql.FieldLTE(FieldCsex, v))
+}
+
+// CageEQ applies the EQ predicate on the "cage" field.
+func CageEQ(v int) predicate.Contact {
+	return predicate.Contact(sql.FieldEQ(FieldCage, v))
+}
+
+// CageNEQ applies the NEQ predicate on the "cage" field.
+func CageNEQ(v int) predicate.Contact {
+	return predicate.Contact(sql.FieldNEQ(FieldCage, v))
+}
+
+// CageIn applies the In predicate on the "cage" field.
+func CageIn(vs ...int) predicate.Contact {
+	return predicate.Contact(sql.FieldIn(FieldCage, vs...))
+}
+
+// CageNotIn applies the NotIn predicate on the "cage" field.
+func CageNotIn(vs ...int) predicate.Contact {
+	return predicate.Contact(sql.FieldNotIn(FieldCage, vs...))
+}
+
+// CageGT applies the GT predicate on the "cage" field.
+func CageGT(v int) predicate.Contact {
+	return predicate.Contact(sql.FieldGT(FieldCage, v))
+}
+
+// CageGTE applies the GTE predicate on the "cage" field.
+func CageGTE(v int) predicate.Contact {
+	return predicate.Contact(sql.FieldGTE(FieldCage, v))
+}
+
+// CageLT applies the LT predicate on the "cage" field.
+func CageLT(v int) predicate.Contact {
+	return predicate.Contact(sql.FieldLT(FieldCage, v))
+}
+
+// CageLTE applies the LTE predicate on the "cage" field.
+func CageLTE(v int) predicate.Contact {
+	return predicate.Contact(sql.FieldLTE(FieldCage, v))
+}
+
+// CnameEQ applies the EQ predicate on the "cname" field.
+func CnameEQ(v string) predicate.Contact {
+	return predicate.Contact(sql.FieldEQ(FieldCname, v))
+}
+
+// CnameNEQ applies the NEQ predicate on the "cname" field.
+func CnameNEQ(v string) predicate.Contact {
+	return predicate.Contact(sql.FieldNEQ(FieldCname, v))
+}
+
+// CnameIn applies the In predicate on the "cname" field.
+func CnameIn(vs ...string) predicate.Contact {
+	return predicate.Contact(sql.FieldIn(FieldCname, vs...))
+}
+
+// CnameNotIn applies the NotIn predicate on the "cname" field.
+func CnameNotIn(vs ...string) predicate.Contact {
+	return predicate.Contact(sql.FieldNotIn(FieldCname, vs...))
+}
+
+// CnameGT applies the GT predicate on the "cname" field.
+func CnameGT(v string) predicate.Contact {
+	return predicate.Contact(sql.FieldGT(FieldCname, v))
+}
+
+// CnameGTE applies the GTE predicate on the "cname" field.
+func CnameGTE(v string) predicate.Contact {
+	return predicate.Contact(sql.FieldGTE(FieldCname, v))
+}
+
+// CnameLT applies the LT predicate on the "cname" field.
+func CnameLT(v string) predicate.Contact {
+	return predicate.Contact(sql.FieldLT(FieldCname, v))
+}
+
+// CnameLTE applies the LTE predicate on the "cname" field.
+func CnameLTE(v string) predicate.Contact {
+	return predicate.Contact(sql.FieldLTE(FieldCname, v))
+}
+
+// CnameContains applies the Contains predicate on the "cname" field.
+func CnameContains(v string) predicate.Contact {
+	return predicate.Contact(sql.FieldContains(FieldCname, v))
+}
+
+// CnameHasPrefix applies the HasPrefix predicate on the "cname" field.
+func CnameHasPrefix(v string) predicate.Contact {
+	return predicate.Contact(sql.FieldHasPrefix(FieldCname, v))
+}
+
+// CnameHasSuffix applies the HasSuffix predicate on the "cname" field.
+func CnameHasSuffix(v string) predicate.Contact {
+	return predicate.Contact(sql.FieldHasSuffix(FieldCname, v))
+}
+
+// CnameEqualFold applies the EqualFold predicate on the "cname" field.
+func CnameEqualFold(v string) predicate.Contact {
+	return predicate.Contact(sql.FieldEqualFold(FieldCname, v))
+}
+
+// CnameContainsFold applies the ContainsFold predicate on the "cname" field.
+func CnameContainsFold(v string) predicate.Contact {
+	return predicate.Contact(sql.FieldContainsFold(FieldCname, v))
+}
+
+// CareaEQ applies the EQ predicate on the "carea" field.
+func CareaEQ(v string) predicate.Contact {
+	return predicate.Contact(sql.FieldEQ(FieldCarea, v))
+}
+
+// CareaNEQ applies the NEQ predicate on the "carea" field.
+func CareaNEQ(v string) predicate.Contact {
+	return predicate.Contact(sql.FieldNEQ(FieldCarea, v))
+}
+
+// CareaIn applies the In predicate on the "carea" field.
+func CareaIn(vs ...string) predicate.Contact {
+	return predicate.Contact(sql.FieldIn(FieldCarea, vs...))
+}
+
+// CareaNotIn applies the NotIn predicate on the "carea" field.
+func CareaNotIn(vs ...string) predicate.Contact {
+	return predicate.Contact(sql.FieldNotIn(FieldCarea, vs...))
+}
+
+// CareaGT applies the GT predicate on the "carea" field.
+func CareaGT(v string) predicate.Contact {
+	return predicate.Contact(sql.FieldGT(FieldCarea, v))
+}
+
+// CareaGTE applies the GTE predicate on the "carea" field.
+func CareaGTE(v string) predicate.Contact {
+	return predicate.Contact(sql.FieldGTE(FieldCarea, v))
+}
+
+// CareaLT applies the LT predicate on the "carea" field.
+func CareaLT(v string) predicate.Contact {
+	return predicate.Contact(sql.FieldLT(FieldCarea, v))
+}
+
+// CareaLTE applies the LTE predicate on the "carea" field.
+func CareaLTE(v string) predicate.Contact {
+	return predicate.Contact(sql.FieldLTE(FieldCarea, v))
+}
+
+// CareaContains applies the Contains predicate on the "carea" field.
+func CareaContains(v string) predicate.Contact {
+	return predicate.Contact(sql.FieldContains(FieldCarea, v))
+}
+
+// CareaHasPrefix applies the HasPrefix predicate on the "carea" field.
+func CareaHasPrefix(v string) predicate.Contact {
+	return predicate.Contact(sql.FieldHasPrefix(FieldCarea, v))
+}
+
+// CareaHasSuffix applies the HasSuffix predicate on the "carea" field.
+func CareaHasSuffix(v string) predicate.Contact {
+	return predicate.Contact(sql.FieldHasSuffix(FieldCarea, v))
+}
+
+// CareaEqualFold applies the EqualFold predicate on the "carea" field.
+func CareaEqualFold(v string) predicate.Contact {
+	return predicate.Contact(sql.FieldEqualFold(FieldCarea, v))
+}
+
+// CareaContainsFold applies the ContainsFold predicate on the "carea" field.
+func CareaContainsFold(v string) predicate.Contact {
+	return predicate.Contact(sql.FieldContainsFold(FieldCarea, v))
+}
+
+// CmobileEQ applies the EQ predicate on the "cmobile" field.
+func CmobileEQ(v string) predicate.Contact {
+	return predicate.Contact(sql.FieldEQ(FieldCmobile, v))
+}
+
+// CmobileNEQ applies the NEQ predicate on the "cmobile" field.
+func CmobileNEQ(v string) predicate.Contact {
+	return predicate.Contact(sql.FieldNEQ(FieldCmobile, v))
+}
+
+// CmobileIn applies the In predicate on the "cmobile" field.
+func CmobileIn(vs ...string) predicate.Contact {
+	return predicate.Contact(sql.FieldIn(FieldCmobile, vs...))
+}
+
+// CmobileNotIn applies the NotIn predicate on the "cmobile" field.
+func CmobileNotIn(vs ...string) predicate.Contact {
+	return predicate.Contact(sql.FieldNotIn(FieldCmobile, vs...))
+}
+
+// CmobileGT applies the GT predicate on the "cmobile" field.
+func CmobileGT(v string) predicate.Contact {
+	return predicate.Contact(sql.FieldGT(FieldCmobile, v))
+}
+
+// CmobileGTE applies the GTE predicate on the "cmobile" field.
+func CmobileGTE(v string) predicate.Contact {
+	return predicate.Contact(sql.FieldGTE(FieldCmobile, v))
+}
+
+// CmobileLT applies the LT predicate on the "cmobile" field.
+func CmobileLT(v string) predicate.Contact {
+	return predicate.Contact(sql.FieldLT(FieldCmobile, v))
+}
+
+// CmobileLTE applies the LTE predicate on the "cmobile" field.
+func CmobileLTE(v string) predicate.Contact {
+	return predicate.Contact(sql.FieldLTE(FieldCmobile, v))
+}
+
+// CmobileContains applies the Contains predicate on the "cmobile" field.
+func CmobileContains(v string) predicate.Contact {
+	return predicate.Contact(sql.FieldContains(FieldCmobile, v))
+}
+
+// CmobileHasPrefix applies the HasPrefix predicate on the "cmobile" field.
+func CmobileHasPrefix(v string) predicate.Contact {
+	return predicate.Contact(sql.FieldHasPrefix(FieldCmobile, v))
+}
+
+// CmobileHasSuffix applies the HasSuffix predicate on the "cmobile" field.
+func CmobileHasSuffix(v string) predicate.Contact {
+	return predicate.Contact(sql.FieldHasSuffix(FieldCmobile, v))
+}
+
+// CmobileEqualFold applies the EqualFold predicate on the "cmobile" field.
+func CmobileEqualFold(v string) predicate.Contact {
+	return predicate.Contact(sql.FieldEqualFold(FieldCmobile, v))
+}
+
+// CmobileContainsFold applies the ContainsFold predicate on the "cmobile" field.
+func CmobileContainsFold(v string) predicate.Contact {
+	return predicate.Contact(sql.FieldContainsFold(FieldCmobile, v))
+}
+
+// CbirthdayEQ applies the EQ predicate on the "cbirthday" field.
+func CbirthdayEQ(v string) predicate.Contact {
+	return predicate.Contact(sql.FieldEQ(FieldCbirthday, v))
+}
+
+// CbirthdayNEQ applies the NEQ predicate on the "cbirthday" field.
+func CbirthdayNEQ(v string) predicate.Contact {
+	return predicate.Contact(sql.FieldNEQ(FieldCbirthday, v))
+}
+
+// CbirthdayIn applies the In predicate on the "cbirthday" field.
+func CbirthdayIn(vs ...string) predicate.Contact {
+	return predicate.Contact(sql.FieldIn(FieldCbirthday, vs...))
+}
+
+// CbirthdayNotIn applies the NotIn predicate on the "cbirthday" field.
+func CbirthdayNotIn(vs ...string) predicate.Contact {
+	return predicate.Contact(sql.FieldNotIn(FieldCbirthday, vs...))
+}
+
+// CbirthdayGT applies the GT predicate on the "cbirthday" field.
+func CbirthdayGT(v string) predicate.Contact {
+	return predicate.Contact(sql.FieldGT(FieldCbirthday, v))
+}
+
+// CbirthdayGTE applies the GTE predicate on the "cbirthday" field.
+func CbirthdayGTE(v string) predicate.Contact {
+	return predicate.Contact(sql.FieldGTE(FieldCbirthday, v))
+}
+
+// CbirthdayLT applies the LT predicate on the "cbirthday" field.
+func CbirthdayLT(v string) predicate.Contact {
+	return predicate.Contact(sql.FieldLT(FieldCbirthday, v))
+}
+
+// CbirthdayLTE applies the LTE predicate on the "cbirthday" field.
+func CbirthdayLTE(v string) predicate.Contact {
+	return predicate.Contact(sql.FieldLTE(FieldCbirthday, v))
+}
+
+// CbirthdayContains applies the Contains predicate on the "cbirthday" field.
+func CbirthdayContains(v string) predicate.Contact {
+	return predicate.Contact(sql.FieldContains(FieldCbirthday, v))
+}
+
+// CbirthdayHasPrefix applies the HasPrefix predicate on the "cbirthday" field.
+func CbirthdayHasPrefix(v string) predicate.Contact {
+	return predicate.Contact(sql.FieldHasPrefix(FieldCbirthday, v))
+}
+
+// CbirthdayHasSuffix applies the HasSuffix predicate on the "cbirthday" field.
+func CbirthdayHasSuffix(v string) predicate.Contact {
+	return predicate.Contact(sql.FieldHasSuffix(FieldCbirthday, v))
+}
+
+// CbirthdayEqualFold applies the EqualFold predicate on the "cbirthday" field.
+func CbirthdayEqualFold(v string) predicate.Contact {
+	return predicate.Contact(sql.FieldEqualFold(FieldCbirthday, v))
+}
+
+// CbirthdayContainsFold applies the ContainsFold predicate on the "cbirthday" field.
+func CbirthdayContainsFold(v string) predicate.Contact {
+	return predicate.Contact(sql.FieldContainsFold(FieldCbirthday, v))
+}
+
+// CbirthareaEQ applies the EQ predicate on the "cbirtharea" field.
+func CbirthareaEQ(v string) predicate.Contact {
+	return predicate.Contact(sql.FieldEQ(FieldCbirtharea, v))
+}
+
+// CbirthareaNEQ applies the NEQ predicate on the "cbirtharea" field.
+func CbirthareaNEQ(v string) predicate.Contact {
+	return predicate.Contact(sql.FieldNEQ(FieldCbirtharea, v))
+}
+
+// CbirthareaIn applies the In predicate on the "cbirtharea" field.
+func CbirthareaIn(vs ...string) predicate.Contact {
+	return predicate.Contact(sql.FieldIn(FieldCbirtharea, vs...))
+}
+
+// CbirthareaNotIn applies the NotIn predicate on the "cbirtharea" field.
+func CbirthareaNotIn(vs ...string) predicate.Contact {
+	return predicate.Contact(sql.FieldNotIn(FieldCbirtharea, vs...))
+}
+
+// CbirthareaGT applies the GT predicate on the "cbirtharea" field.
+func CbirthareaGT(v string) predicate.Contact {
+	return predicate.Contact(sql.FieldGT(FieldCbirtharea, v))
+}
+
+// CbirthareaGTE applies the GTE predicate on the "cbirtharea" field.
+func CbirthareaGTE(v string) predicate.Contact {
+	return predicate.Contact(sql.FieldGTE(FieldCbirtharea, v))
+}
+
+// CbirthareaLT applies the LT predicate on the "cbirtharea" field.
+func CbirthareaLT(v string) predicate.Contact {
+	return predicate.Contact(sql.FieldLT(FieldCbirtharea, v))
+}
+
+// CbirthareaLTE applies the LTE predicate on the "cbirtharea" field.
+func CbirthareaLTE(v string) predicate.Contact {
+	return predicate.Contact(sql.FieldLTE(FieldCbirtharea, v))
+}
+
+// CbirthareaContains applies the Contains predicate on the "cbirtharea" field.
+func CbirthareaContains(v string) predicate.Contact {
+	return predicate.Contact(sql.FieldContains(FieldCbirtharea, v))
+}
+
+// CbirthareaHasPrefix applies the HasPrefix predicate on the "cbirtharea" field.
+func CbirthareaHasPrefix(v string) predicate.Contact {
+	return predicate.Contact(sql.FieldHasPrefix(FieldCbirtharea, v))
+}
+
+// CbirthareaHasSuffix applies the HasSuffix predicate on the "cbirtharea" field.
+func CbirthareaHasSuffix(v string) predicate.Contact {
+	return predicate.Contact(sql.FieldHasSuffix(FieldCbirtharea, v))
+}
+
+// CbirthareaEqualFold applies the EqualFold predicate on the "cbirtharea" field.
+func CbirthareaEqualFold(v string) predicate.Contact {
+	return predicate.Contact(sql.FieldEqualFold(FieldCbirtharea, v))
+}
+
+// CbirthareaContainsFold applies the ContainsFold predicate on the "cbirtharea" field.
+func CbirthareaContainsFold(v string) predicate.Contact {
+	return predicate.Contact(sql.FieldContainsFold(FieldCbirtharea, v))
+}
+
+// CidcardNoEQ applies the EQ predicate on the "cidcard_no" field.
+func CidcardNoEQ(v string) predicate.Contact {
+	return predicate.Contact(sql.FieldEQ(FieldCidcardNo, v))
+}
+
+// CidcardNoNEQ applies the NEQ predicate on the "cidcard_no" field.
+func CidcardNoNEQ(v string) predicate.Contact {
+	return predicate.Contact(sql.FieldNEQ(FieldCidcardNo, v))
+}
+
+// CidcardNoIn applies the In predicate on the "cidcard_no" field.
+func CidcardNoIn(vs ...string) predicate.Contact {
+	return predicate.Contact(sql.FieldIn(FieldCidcardNo, vs...))
+}
+
+// CidcardNoNotIn applies the NotIn predicate on the "cidcard_no" field.
+func CidcardNoNotIn(vs ...string) predicate.Contact {
+	return predicate.Contact(sql.FieldNotIn(FieldCidcardNo, vs...))
+}
+
+// CidcardNoGT applies the GT predicate on the "cidcard_no" field.
+func CidcardNoGT(v string) predicate.Contact {
+	return predicate.Contact(sql.FieldGT(FieldCidcardNo, v))
+}
+
+// CidcardNoGTE applies the GTE predicate on the "cidcard_no" field.
+func CidcardNoGTE(v string) predicate.Contact {
+	return predicate.Contact(sql.FieldGTE(FieldCidcardNo, v))
+}
+
+// CidcardNoLT applies the LT predicate on the "cidcard_no" field.
+func CidcardNoLT(v string) predicate.Contact {
+	return predicate.Contact(sql.FieldLT(FieldCidcardNo, v))
+}
+
+// CidcardNoLTE applies the LTE predicate on the "cidcard_no" field.
+func CidcardNoLTE(v string) predicate.Contact {
+	return predicate.Contact(sql.FieldLTE(FieldCidcardNo, v))
+}
+
+// CidcardNoContains applies the Contains predicate on the "cidcard_no" field.
+func CidcardNoContains(v string) predicate.Contact {
+	return predicate.Contact(sql.FieldContains(FieldCidcardNo, v))
+}
+
+// CidcardNoHasPrefix applies the HasPrefix predicate on the "cidcard_no" field.
+func CidcardNoHasPrefix(v string) predicate.Contact {
+	return predicate.Contact(sql.FieldHasPrefix(FieldCidcardNo, v))
+}
+
+// CidcardNoHasSuffix applies the HasSuffix predicate on the "cidcard_no" field.
+func CidcardNoHasSuffix(v string) predicate.Contact {
+	return predicate.Contact(sql.FieldHasSuffix(FieldCidcardNo, v))
+}
+
+// CidcardNoEqualFold applies the EqualFold predicate on the "cidcard_no" field.
+func CidcardNoEqualFold(v string) predicate.Contact {
+	return predicate.Contact(sql.FieldEqualFold(FieldCidcardNo, v))
+}
+
+// CidcardNoContainsFold applies the ContainsFold predicate on the "cidcard_no" field.
+func CidcardNoContainsFold(v string) predicate.Contact {
+	return predicate.Contact(sql.FieldContainsFold(FieldCidcardNo, v))
+}
+
+// CtitleEQ applies the EQ predicate on the "ctitle" field.
+func CtitleEQ(v string) predicate.Contact {
+	return predicate.Contact(sql.FieldEQ(FieldCtitle, v))
+}
+
+// CtitleNEQ applies the NEQ predicate on the "ctitle" field.
+func CtitleNEQ(v string) predicate.Contact {
+	return predicate.Contact(sql.FieldNEQ(FieldCtitle, v))
+}
+
+// CtitleIn applies the In predicate on the "ctitle" field.
+func CtitleIn(vs ...string) predicate.Contact {
+	return predicate.Contact(sql.FieldIn(FieldCtitle, vs...))
+}
+
+// CtitleNotIn applies the NotIn predicate on the "ctitle" field.
+func CtitleNotIn(vs ...string) predicate.Contact {
+	return predicate.Contact(sql.FieldNotIn(FieldCtitle, vs...))
+}
+
+// CtitleGT applies the GT predicate on the "ctitle" field.
+func CtitleGT(v string) predicate.Contact {
+	return predicate.Contact(sql.FieldGT(FieldCtitle, v))
+}
+
+// CtitleGTE applies the GTE predicate on the "ctitle" field.
+func CtitleGTE(v string) predicate.Contact {
+	return predicate.Contact(sql.FieldGTE(FieldCtitle, v))
+}
+
+// CtitleLT applies the LT predicate on the "ctitle" field.
+func CtitleLT(v string) predicate.Contact {
+	return predicate.Contact(sql.FieldLT(FieldCtitle, v))
+}
+
+// CtitleLTE applies the LTE predicate on the "ctitle" field.
+func CtitleLTE(v string) predicate.Contact {
+	return predicate.Contact(sql.FieldLTE(FieldCtitle, v))
+}
+
+// CtitleContains applies the Contains predicate on the "ctitle" field.
+func CtitleContains(v string) predicate.Contact {
+	return predicate.Contact(sql.FieldContains(FieldCtitle, v))
+}
+
+// CtitleHasPrefix applies the HasPrefix predicate on the "ctitle" field.
+func CtitleHasPrefix(v string) predicate.Contact {
+	return predicate.Contact(sql.FieldHasPrefix(FieldCtitle, v))
+}
+
+// CtitleHasSuffix applies the HasSuffix predicate on the "ctitle" field.
+func CtitleHasSuffix(v string) predicate.Contact {
+	return predicate.Contact(sql.FieldHasSuffix(FieldCtitle, v))
+}
+
+// CtitleEqualFold applies the EqualFold predicate on the "ctitle" field.
+func CtitleEqualFold(v string) predicate.Contact {
+	return predicate.Contact(sql.FieldEqualFold(FieldCtitle, v))
+}
+
+// CtitleContainsFold applies the ContainsFold predicate on the "ctitle" field.
+func CtitleContainsFold(v string) predicate.Contact {
+	return predicate.Contact(sql.FieldContainsFold(FieldCtitle, v))
+}
+
+// CcEQ applies the EQ predicate on the "cc" field.
+func CcEQ(v string) predicate.Contact {
+	return predicate.Contact(sql.FieldEQ(FieldCc, v))
+}
+
+// CcNEQ applies the NEQ predicate on the "cc" field.
+func CcNEQ(v string) predicate.Contact {
+	return predicate.Contact(sql.FieldNEQ(FieldCc, v))
+}
+
+// CcIn applies the In predicate on the "cc" field.
+func CcIn(vs ...string) predicate.Contact {
+	return predicate.Contact(sql.FieldIn(FieldCc, vs...))
+}
+
+// CcNotIn applies the NotIn predicate on the "cc" field.
+func CcNotIn(vs ...string) predicate.Contact {
+	return predicate.Contact(sql.FieldNotIn(FieldCc, vs...))
+}
+
+// CcGT applies the GT predicate on the "cc" field.
+func CcGT(v string) predicate.Contact {
+	return predicate.Contact(sql.FieldGT(FieldCc, v))
+}
+
+// CcGTE applies the GTE predicate on the "cc" field.
+func CcGTE(v string) predicate.Contact {
+	return predicate.Contact(sql.FieldGTE(FieldCc, v))
+}
+
+// CcLT applies the LT predicate on the "cc" field.
+func CcLT(v string) predicate.Contact {
+	return predicate.Contact(sql.FieldLT(FieldCc, v))
+}
+
+// CcLTE applies the LTE predicate on the "cc" field.
+func CcLTE(v string) predicate.Contact {
+	return predicate.Contact(sql.FieldLTE(FieldCc, v))
+}
+
+// CcContains applies the Contains predicate on the "cc" field.
+func CcContains(v string) predicate.Contact {
+	return predicate.Contact(sql.FieldContains(FieldCc, v))
+}
+
+// CcHasPrefix applies the HasPrefix predicate on the "cc" field.
+func CcHasPrefix(v string) predicate.Contact {
+	return predicate.Contact(sql.FieldHasPrefix(FieldCc, v))
+}
+
+// CcHasSuffix applies the HasSuffix predicate on the "cc" field.
+func CcHasSuffix(v string) predicate.Contact {
+	return predicate.Contact(sql.FieldHasSuffix(FieldCc, v))
+}
+
+// CcEqualFold applies the EqualFold predicate on the "cc" field.
+func CcEqualFold(v string) predicate.Contact {
+	return predicate.Contact(sql.FieldEqualFold(FieldCc, v))
+}
+
+// CcContainsFold applies the ContainsFold predicate on the "cc" field.
+func CcContainsFold(v string) predicate.Contact {
+	return predicate.Contact(sql.FieldContainsFold(FieldCc, v))
+}
+
+// PhoneEQ applies the EQ predicate on the "phone" field.
+func PhoneEQ(v string) predicate.Contact {
+	return predicate.Contact(sql.FieldEQ(FieldPhone, v))
+}
+
+// PhoneNEQ applies the NEQ predicate on the "phone" field.
+func PhoneNEQ(v string) predicate.Contact {
+	return predicate.Contact(sql.FieldNEQ(FieldPhone, v))
+}
+
+// PhoneIn applies the In predicate on the "phone" field.
+func PhoneIn(vs ...string) predicate.Contact {
+	return predicate.Contact(sql.FieldIn(FieldPhone, vs...))
+}
+
+// PhoneNotIn applies the NotIn predicate on the "phone" field.
+func PhoneNotIn(vs ...string) predicate.Contact {
+	return predicate.Contact(sql.FieldNotIn(FieldPhone, vs...))
+}
+
+// PhoneGT applies the GT predicate on the "phone" field.
+func PhoneGT(v string) predicate.Contact {
+	return predicate.Contact(sql.FieldGT(FieldPhone, v))
+}
+
+// PhoneGTE applies the GTE predicate on the "phone" field.
+func PhoneGTE(v string) predicate.Contact {
+	return predicate.Contact(sql.FieldGTE(FieldPhone, v))
+}
+
+// PhoneLT applies the LT predicate on the "phone" field.
+func PhoneLT(v string) predicate.Contact {
+	return predicate.Contact(sql.FieldLT(FieldPhone, v))
+}
+
+// PhoneLTE applies the LTE predicate on the "phone" field.
+func PhoneLTE(v string) predicate.Contact {
+	return predicate.Contact(sql.FieldLTE(FieldPhone, v))
+}
+
+// PhoneContains applies the Contains predicate on the "phone" field.
+func PhoneContains(v string) predicate.Contact {
+	return predicate.Contact(sql.FieldContains(FieldPhone, v))
+}
+
+// PhoneHasPrefix applies the HasPrefix predicate on the "phone" field.
+func PhoneHasPrefix(v string) predicate.Contact {
+	return predicate.Contact(sql.FieldHasPrefix(FieldPhone, v))
+}
+
+// PhoneHasSuffix applies the HasSuffix predicate on the "phone" field.
+func PhoneHasSuffix(v string) predicate.Contact {
+	return predicate.Contact(sql.FieldHasSuffix(FieldPhone, v))
+}
+
+// PhoneEqualFold applies the EqualFold predicate on the "phone" field.
+func PhoneEqualFold(v string) predicate.Contact {
+	return predicate.Contact(sql.FieldEqualFold(FieldPhone, v))
+}
+
+// PhoneContainsFold applies the ContainsFold predicate on the "phone" field.
+func PhoneContainsFold(v string) predicate.Contact {
+	return predicate.Contact(sql.FieldContainsFold(FieldPhone, v))
+}
+
 // HasContactRelationships applies the HasEdge predicate on the "contact_relationships" edge.
 func HasContactRelationships() predicate.Contact {
 	return predicate.Contact(func(s *sql.Selector) {

+ 840 - 0
ent/contact_create.go

@@ -304,6 +304,174 @@ func (cc *ContactCreate) SetNillableOrganizationID(u *uint64) *ContactCreate {
 	return cc
 }
 
+// SetCtype sets the "ctype" field.
+func (cc *ContactCreate) SetCtype(u uint64) *ContactCreate {
+	cc.mutation.SetCtype(u)
+	return cc
+}
+
+// SetNillableCtype sets the "ctype" field if the given value is not nil.
+func (cc *ContactCreate) SetNillableCtype(u *uint64) *ContactCreate {
+	if u != nil {
+		cc.SetCtype(*u)
+	}
+	return cc
+}
+
+// SetCsex sets the "csex" field.
+func (cc *ContactCreate) SetCsex(i int) *ContactCreate {
+	cc.mutation.SetCsex(i)
+	return cc
+}
+
+// SetNillableCsex sets the "csex" field if the given value is not nil.
+func (cc *ContactCreate) SetNillableCsex(i *int) *ContactCreate {
+	if i != nil {
+		cc.SetCsex(*i)
+	}
+	return cc
+}
+
+// SetCage sets the "cage" field.
+func (cc *ContactCreate) SetCage(i int) *ContactCreate {
+	cc.mutation.SetCage(i)
+	return cc
+}
+
+// SetNillableCage sets the "cage" field if the given value is not nil.
+func (cc *ContactCreate) SetNillableCage(i *int) *ContactCreate {
+	if i != nil {
+		cc.SetCage(*i)
+	}
+	return cc
+}
+
+// SetCname sets the "cname" field.
+func (cc *ContactCreate) SetCname(s string) *ContactCreate {
+	cc.mutation.SetCname(s)
+	return cc
+}
+
+// SetNillableCname sets the "cname" field if the given value is not nil.
+func (cc *ContactCreate) SetNillableCname(s *string) *ContactCreate {
+	if s != nil {
+		cc.SetCname(*s)
+	}
+	return cc
+}
+
+// SetCarea sets the "carea" field.
+func (cc *ContactCreate) SetCarea(s string) *ContactCreate {
+	cc.mutation.SetCarea(s)
+	return cc
+}
+
+// SetNillableCarea sets the "carea" field if the given value is not nil.
+func (cc *ContactCreate) SetNillableCarea(s *string) *ContactCreate {
+	if s != nil {
+		cc.SetCarea(*s)
+	}
+	return cc
+}
+
+// SetCmobile sets the "cmobile" field.
+func (cc *ContactCreate) SetCmobile(s string) *ContactCreate {
+	cc.mutation.SetCmobile(s)
+	return cc
+}
+
+// SetNillableCmobile sets the "cmobile" field if the given value is not nil.
+func (cc *ContactCreate) SetNillableCmobile(s *string) *ContactCreate {
+	if s != nil {
+		cc.SetCmobile(*s)
+	}
+	return cc
+}
+
+// SetCbirthday sets the "cbirthday" field.
+func (cc *ContactCreate) SetCbirthday(s string) *ContactCreate {
+	cc.mutation.SetCbirthday(s)
+	return cc
+}
+
+// SetNillableCbirthday sets the "cbirthday" field if the given value is not nil.
+func (cc *ContactCreate) SetNillableCbirthday(s *string) *ContactCreate {
+	if s != nil {
+		cc.SetCbirthday(*s)
+	}
+	return cc
+}
+
+// SetCbirtharea sets the "cbirtharea" field.
+func (cc *ContactCreate) SetCbirtharea(s string) *ContactCreate {
+	cc.mutation.SetCbirtharea(s)
+	return cc
+}
+
+// SetNillableCbirtharea sets the "cbirtharea" field if the given value is not nil.
+func (cc *ContactCreate) SetNillableCbirtharea(s *string) *ContactCreate {
+	if s != nil {
+		cc.SetCbirtharea(*s)
+	}
+	return cc
+}
+
+// SetCidcardNo sets the "cidcard_no" field.
+func (cc *ContactCreate) SetCidcardNo(s string) *ContactCreate {
+	cc.mutation.SetCidcardNo(s)
+	return cc
+}
+
+// SetNillableCidcardNo sets the "cidcard_no" field if the given value is not nil.
+func (cc *ContactCreate) SetNillableCidcardNo(s *string) *ContactCreate {
+	if s != nil {
+		cc.SetCidcardNo(*s)
+	}
+	return cc
+}
+
+// SetCtitle sets the "ctitle" field.
+func (cc *ContactCreate) SetCtitle(s string) *ContactCreate {
+	cc.mutation.SetCtitle(s)
+	return cc
+}
+
+// SetNillableCtitle sets the "ctitle" field if the given value is not nil.
+func (cc *ContactCreate) SetNillableCtitle(s *string) *ContactCreate {
+	if s != nil {
+		cc.SetCtitle(*s)
+	}
+	return cc
+}
+
+// SetCc sets the "cc" field.
+func (cc *ContactCreate) SetCc(s string) *ContactCreate {
+	cc.mutation.SetCc(s)
+	return cc
+}
+
+// SetNillableCc sets the "cc" field if the given value is not nil.
+func (cc *ContactCreate) SetNillableCc(s *string) *ContactCreate {
+	if s != nil {
+		cc.SetCc(*s)
+	}
+	return cc
+}
+
+// SetPhone sets the "phone" field.
+func (cc *ContactCreate) SetPhone(s string) *ContactCreate {
+	cc.mutation.SetPhone(s)
+	return cc
+}
+
+// SetNillablePhone sets the "phone" field if the given value is not nil.
+func (cc *ContactCreate) SetNillablePhone(s *string) *ContactCreate {
+	if s != nil {
+		cc.SetPhone(*s)
+	}
+	return cc
+}
+
 // SetID sets the "id" field.
 func (cc *ContactCreate) SetID(u uint64) *ContactCreate {
 	cc.mutation.SetID(u)
@@ -459,6 +627,54 @@ func (cc *ContactCreate) defaults() error {
 		v := contact.DefaultOrganizationID
 		cc.mutation.SetOrganizationID(v)
 	}
+	if _, ok := cc.mutation.Ctype(); !ok {
+		v := contact.DefaultCtype
+		cc.mutation.SetCtype(v)
+	}
+	if _, ok := cc.mutation.Csex(); !ok {
+		v := contact.DefaultCsex
+		cc.mutation.SetCsex(v)
+	}
+	if _, ok := cc.mutation.Cage(); !ok {
+		v := contact.DefaultCage
+		cc.mutation.SetCage(v)
+	}
+	if _, ok := cc.mutation.Cname(); !ok {
+		v := contact.DefaultCname
+		cc.mutation.SetCname(v)
+	}
+	if _, ok := cc.mutation.Carea(); !ok {
+		v := contact.DefaultCarea
+		cc.mutation.SetCarea(v)
+	}
+	if _, ok := cc.mutation.Cmobile(); !ok {
+		v := contact.DefaultCmobile
+		cc.mutation.SetCmobile(v)
+	}
+	if _, ok := cc.mutation.Cbirthday(); !ok {
+		v := contact.DefaultCbirthday
+		cc.mutation.SetCbirthday(v)
+	}
+	if _, ok := cc.mutation.Cbirtharea(); !ok {
+		v := contact.DefaultCbirtharea
+		cc.mutation.SetCbirtharea(v)
+	}
+	if _, ok := cc.mutation.CidcardNo(); !ok {
+		v := contact.DefaultCidcardNo
+		cc.mutation.SetCidcardNo(v)
+	}
+	if _, ok := cc.mutation.Ctitle(); !ok {
+		v := contact.DefaultCtitle
+		cc.mutation.SetCtitle(v)
+	}
+	if _, ok := cc.mutation.Cc(); !ok {
+		v := contact.DefaultCc
+		cc.mutation.SetCc(v)
+	}
+	if _, ok := cc.mutation.Phone(); !ok {
+		v := contact.DefaultPhone
+		cc.mutation.SetPhone(v)
+	}
 	return nil
 }
 
@@ -512,6 +728,42 @@ func (cc *ContactCreate) check() error {
 	if _, ok := cc.mutation.V3(); !ok {
 		return &ValidationError{Name: "v3", err: errors.New(`ent: missing required field "Contact.v3"`)}
 	}
+	if _, ok := cc.mutation.Ctype(); !ok {
+		return &ValidationError{Name: "ctype", err: errors.New(`ent: missing required field "Contact.ctype"`)}
+	}
+	if _, ok := cc.mutation.Csex(); !ok {
+		return &ValidationError{Name: "csex", err: errors.New(`ent: missing required field "Contact.csex"`)}
+	}
+	if _, ok := cc.mutation.Cage(); !ok {
+		return &ValidationError{Name: "cage", err: errors.New(`ent: missing required field "Contact.cage"`)}
+	}
+	if _, ok := cc.mutation.Cname(); !ok {
+		return &ValidationError{Name: "cname", err: errors.New(`ent: missing required field "Contact.cname"`)}
+	}
+	if _, ok := cc.mutation.Carea(); !ok {
+		return &ValidationError{Name: "carea", err: errors.New(`ent: missing required field "Contact.carea"`)}
+	}
+	if _, ok := cc.mutation.Cmobile(); !ok {
+		return &ValidationError{Name: "cmobile", err: errors.New(`ent: missing required field "Contact.cmobile"`)}
+	}
+	if _, ok := cc.mutation.Cbirthday(); !ok {
+		return &ValidationError{Name: "cbirthday", err: errors.New(`ent: missing required field "Contact.cbirthday"`)}
+	}
+	if _, ok := cc.mutation.Cbirtharea(); !ok {
+		return &ValidationError{Name: "cbirtharea", err: errors.New(`ent: missing required field "Contact.cbirtharea"`)}
+	}
+	if _, ok := cc.mutation.CidcardNo(); !ok {
+		return &ValidationError{Name: "cidcard_no", err: errors.New(`ent: missing required field "Contact.cidcard_no"`)}
+	}
+	if _, ok := cc.mutation.Ctitle(); !ok {
+		return &ValidationError{Name: "ctitle", err: errors.New(`ent: missing required field "Contact.ctitle"`)}
+	}
+	if _, ok := cc.mutation.Cc(); !ok {
+		return &ValidationError{Name: "cc", err: errors.New(`ent: missing required field "Contact.cc"`)}
+	}
+	if _, ok := cc.mutation.Phone(); !ok {
+		return &ValidationError{Name: "phone", err: errors.New(`ent: missing required field "Contact.phone"`)}
+	}
 	return nil
 }
 
@@ -625,6 +877,54 @@ func (cc *ContactCreate) createSpec() (*Contact, *sqlgraph.CreateSpec) {
 		_spec.SetField(contact.FieldOrganizationID, field.TypeUint64, value)
 		_node.OrganizationID = value
 	}
+	if value, ok := cc.mutation.Ctype(); ok {
+		_spec.SetField(contact.FieldCtype, field.TypeUint64, value)
+		_node.Ctype = value
+	}
+	if value, ok := cc.mutation.Csex(); ok {
+		_spec.SetField(contact.FieldCsex, field.TypeInt, value)
+		_node.Csex = value
+	}
+	if value, ok := cc.mutation.Cage(); ok {
+		_spec.SetField(contact.FieldCage, field.TypeInt, value)
+		_node.Cage = value
+	}
+	if value, ok := cc.mutation.Cname(); ok {
+		_spec.SetField(contact.FieldCname, field.TypeString, value)
+		_node.Cname = value
+	}
+	if value, ok := cc.mutation.Carea(); ok {
+		_spec.SetField(contact.FieldCarea, field.TypeString, value)
+		_node.Carea = value
+	}
+	if value, ok := cc.mutation.Cmobile(); ok {
+		_spec.SetField(contact.FieldCmobile, field.TypeString, value)
+		_node.Cmobile = value
+	}
+	if value, ok := cc.mutation.Cbirthday(); ok {
+		_spec.SetField(contact.FieldCbirthday, field.TypeString, value)
+		_node.Cbirthday = value
+	}
+	if value, ok := cc.mutation.Cbirtharea(); ok {
+		_spec.SetField(contact.FieldCbirtharea, field.TypeString, value)
+		_node.Cbirtharea = value
+	}
+	if value, ok := cc.mutation.CidcardNo(); ok {
+		_spec.SetField(contact.FieldCidcardNo, field.TypeString, value)
+		_node.CidcardNo = value
+	}
+	if value, ok := cc.mutation.Ctitle(); ok {
+		_spec.SetField(contact.FieldCtitle, field.TypeString, value)
+		_node.Ctitle = value
+	}
+	if value, ok := cc.mutation.Cc(); ok {
+		_spec.SetField(contact.FieldCc, field.TypeString, value)
+		_node.Cc = value
+	}
+	if value, ok := cc.mutation.Phone(); ok {
+		_spec.SetField(contact.FieldPhone, field.TypeString, value)
+		_node.Phone = value
+	}
 	if nodes := cc.mutation.ContactRelationshipsIDs(); len(nodes) > 0 {
 		edge := &sqlgraph.EdgeSpec{
 			Rel:     sqlgraph.O2M,
@@ -997,6 +1297,168 @@ func (u *ContactUpsert) ClearOrganizationID() *ContactUpsert {
 	return u
 }
 
+// SetCtype sets the "ctype" field.
+func (u *ContactUpsert) SetCtype(v uint64) *ContactUpsert {
+	u.Set(contact.FieldCtype, v)
+	return u
+}
+
+// UpdateCtype sets the "ctype" field to the value that was provided on create.
+func (u *ContactUpsert) UpdateCtype() *ContactUpsert {
+	u.SetExcluded(contact.FieldCtype)
+	return u
+}
+
+// AddCtype adds v to the "ctype" field.
+func (u *ContactUpsert) AddCtype(v uint64) *ContactUpsert {
+	u.Add(contact.FieldCtype, v)
+	return u
+}
+
+// SetCsex sets the "csex" field.
+func (u *ContactUpsert) SetCsex(v int) *ContactUpsert {
+	u.Set(contact.FieldCsex, v)
+	return u
+}
+
+// UpdateCsex sets the "csex" field to the value that was provided on create.
+func (u *ContactUpsert) UpdateCsex() *ContactUpsert {
+	u.SetExcluded(contact.FieldCsex)
+	return u
+}
+
+// AddCsex adds v to the "csex" field.
+func (u *ContactUpsert) AddCsex(v int) *ContactUpsert {
+	u.Add(contact.FieldCsex, v)
+	return u
+}
+
+// SetCage sets the "cage" field.
+func (u *ContactUpsert) SetCage(v int) *ContactUpsert {
+	u.Set(contact.FieldCage, v)
+	return u
+}
+
+// UpdateCage sets the "cage" field to the value that was provided on create.
+func (u *ContactUpsert) UpdateCage() *ContactUpsert {
+	u.SetExcluded(contact.FieldCage)
+	return u
+}
+
+// AddCage adds v to the "cage" field.
+func (u *ContactUpsert) AddCage(v int) *ContactUpsert {
+	u.Add(contact.FieldCage, v)
+	return u
+}
+
+// SetCname sets the "cname" field.
+func (u *ContactUpsert) SetCname(v string) *ContactUpsert {
+	u.Set(contact.FieldCname, v)
+	return u
+}
+
+// UpdateCname sets the "cname" field to the value that was provided on create.
+func (u *ContactUpsert) UpdateCname() *ContactUpsert {
+	u.SetExcluded(contact.FieldCname)
+	return u
+}
+
+// SetCarea sets the "carea" field.
+func (u *ContactUpsert) SetCarea(v string) *ContactUpsert {
+	u.Set(contact.FieldCarea, v)
+	return u
+}
+
+// UpdateCarea sets the "carea" field to the value that was provided on create.
+func (u *ContactUpsert) UpdateCarea() *ContactUpsert {
+	u.SetExcluded(contact.FieldCarea)
+	return u
+}
+
+// SetCmobile sets the "cmobile" field.
+func (u *ContactUpsert) SetCmobile(v string) *ContactUpsert {
+	u.Set(contact.FieldCmobile, v)
+	return u
+}
+
+// UpdateCmobile sets the "cmobile" field to the value that was provided on create.
+func (u *ContactUpsert) UpdateCmobile() *ContactUpsert {
+	u.SetExcluded(contact.FieldCmobile)
+	return u
+}
+
+// SetCbirthday sets the "cbirthday" field.
+func (u *ContactUpsert) SetCbirthday(v string) *ContactUpsert {
+	u.Set(contact.FieldCbirthday, v)
+	return u
+}
+
+// UpdateCbirthday sets the "cbirthday" field to the value that was provided on create.
+func (u *ContactUpsert) UpdateCbirthday() *ContactUpsert {
+	u.SetExcluded(contact.FieldCbirthday)
+	return u
+}
+
+// SetCbirtharea sets the "cbirtharea" field.
+func (u *ContactUpsert) SetCbirtharea(v string) *ContactUpsert {
+	u.Set(contact.FieldCbirtharea, v)
+	return u
+}
+
+// UpdateCbirtharea sets the "cbirtharea" field to the value that was provided on create.
+func (u *ContactUpsert) UpdateCbirtharea() *ContactUpsert {
+	u.SetExcluded(contact.FieldCbirtharea)
+	return u
+}
+
+// SetCidcardNo sets the "cidcard_no" field.
+func (u *ContactUpsert) SetCidcardNo(v string) *ContactUpsert {
+	u.Set(contact.FieldCidcardNo, v)
+	return u
+}
+
+// UpdateCidcardNo sets the "cidcard_no" field to the value that was provided on create.
+func (u *ContactUpsert) UpdateCidcardNo() *ContactUpsert {
+	u.SetExcluded(contact.FieldCidcardNo)
+	return u
+}
+
+// SetCtitle sets the "ctitle" field.
+func (u *ContactUpsert) SetCtitle(v string) *ContactUpsert {
+	u.Set(contact.FieldCtitle, v)
+	return u
+}
+
+// UpdateCtitle sets the "ctitle" field to the value that was provided on create.
+func (u *ContactUpsert) UpdateCtitle() *ContactUpsert {
+	u.SetExcluded(contact.FieldCtitle)
+	return u
+}
+
+// SetCc sets the "cc" field.
+func (u *ContactUpsert) SetCc(v string) *ContactUpsert {
+	u.Set(contact.FieldCc, v)
+	return u
+}
+
+// UpdateCc sets the "cc" field to the value that was provided on create.
+func (u *ContactUpsert) UpdateCc() *ContactUpsert {
+	u.SetExcluded(contact.FieldCc)
+	return u
+}
+
+// SetPhone sets the "phone" field.
+func (u *ContactUpsert) SetPhone(v string) *ContactUpsert {
+	u.Set(contact.FieldPhone, v)
+	return u
+}
+
+// UpdatePhone sets the "phone" field to the value that was provided on create.
+func (u *ContactUpsert) UpdatePhone() *ContactUpsert {
+	u.SetExcluded(contact.FieldPhone)
+	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:
 //
@@ -1384,6 +1846,195 @@ func (u *ContactUpsertOne) ClearOrganizationID() *ContactUpsertOne {
 	})
 }
 
+// SetCtype sets the "ctype" field.
+func (u *ContactUpsertOne) SetCtype(v uint64) *ContactUpsertOne {
+	return u.Update(func(s *ContactUpsert) {
+		s.SetCtype(v)
+	})
+}
+
+// AddCtype adds v to the "ctype" field.
+func (u *ContactUpsertOne) AddCtype(v uint64) *ContactUpsertOne {
+	return u.Update(func(s *ContactUpsert) {
+		s.AddCtype(v)
+	})
+}
+
+// UpdateCtype sets the "ctype" field to the value that was provided on create.
+func (u *ContactUpsertOne) UpdateCtype() *ContactUpsertOne {
+	return u.Update(func(s *ContactUpsert) {
+		s.UpdateCtype()
+	})
+}
+
+// SetCsex sets the "csex" field.
+func (u *ContactUpsertOne) SetCsex(v int) *ContactUpsertOne {
+	return u.Update(func(s *ContactUpsert) {
+		s.SetCsex(v)
+	})
+}
+
+// AddCsex adds v to the "csex" field.
+func (u *ContactUpsertOne) AddCsex(v int) *ContactUpsertOne {
+	return u.Update(func(s *ContactUpsert) {
+		s.AddCsex(v)
+	})
+}
+
+// UpdateCsex sets the "csex" field to the value that was provided on create.
+func (u *ContactUpsertOne) UpdateCsex() *ContactUpsertOne {
+	return u.Update(func(s *ContactUpsert) {
+		s.UpdateCsex()
+	})
+}
+
+// SetCage sets the "cage" field.
+func (u *ContactUpsertOne) SetCage(v int) *ContactUpsertOne {
+	return u.Update(func(s *ContactUpsert) {
+		s.SetCage(v)
+	})
+}
+
+// AddCage adds v to the "cage" field.
+func (u *ContactUpsertOne) AddCage(v int) *ContactUpsertOne {
+	return u.Update(func(s *ContactUpsert) {
+		s.AddCage(v)
+	})
+}
+
+// UpdateCage sets the "cage" field to the value that was provided on create.
+func (u *ContactUpsertOne) UpdateCage() *ContactUpsertOne {
+	return u.Update(func(s *ContactUpsert) {
+		s.UpdateCage()
+	})
+}
+
+// SetCname sets the "cname" field.
+func (u *ContactUpsertOne) SetCname(v string) *ContactUpsertOne {
+	return u.Update(func(s *ContactUpsert) {
+		s.SetCname(v)
+	})
+}
+
+// UpdateCname sets the "cname" field to the value that was provided on create.
+func (u *ContactUpsertOne) UpdateCname() *ContactUpsertOne {
+	return u.Update(func(s *ContactUpsert) {
+		s.UpdateCname()
+	})
+}
+
+// SetCarea sets the "carea" field.
+func (u *ContactUpsertOne) SetCarea(v string) *ContactUpsertOne {
+	return u.Update(func(s *ContactUpsert) {
+		s.SetCarea(v)
+	})
+}
+
+// UpdateCarea sets the "carea" field to the value that was provided on create.
+func (u *ContactUpsertOne) UpdateCarea() *ContactUpsertOne {
+	return u.Update(func(s *ContactUpsert) {
+		s.UpdateCarea()
+	})
+}
+
+// SetCmobile sets the "cmobile" field.
+func (u *ContactUpsertOne) SetCmobile(v string) *ContactUpsertOne {
+	return u.Update(func(s *ContactUpsert) {
+		s.SetCmobile(v)
+	})
+}
+
+// UpdateCmobile sets the "cmobile" field to the value that was provided on create.
+func (u *ContactUpsertOne) UpdateCmobile() *ContactUpsertOne {
+	return u.Update(func(s *ContactUpsert) {
+		s.UpdateCmobile()
+	})
+}
+
+// SetCbirthday sets the "cbirthday" field.
+func (u *ContactUpsertOne) SetCbirthday(v string) *ContactUpsertOne {
+	return u.Update(func(s *ContactUpsert) {
+		s.SetCbirthday(v)
+	})
+}
+
+// UpdateCbirthday sets the "cbirthday" field to the value that was provided on create.
+func (u *ContactUpsertOne) UpdateCbirthday() *ContactUpsertOne {
+	return u.Update(func(s *ContactUpsert) {
+		s.UpdateCbirthday()
+	})
+}
+
+// SetCbirtharea sets the "cbirtharea" field.
+func (u *ContactUpsertOne) SetCbirtharea(v string) *ContactUpsertOne {
+	return u.Update(func(s *ContactUpsert) {
+		s.SetCbirtharea(v)
+	})
+}
+
+// UpdateCbirtharea sets the "cbirtharea" field to the value that was provided on create.
+func (u *ContactUpsertOne) UpdateCbirtharea() *ContactUpsertOne {
+	return u.Update(func(s *ContactUpsert) {
+		s.UpdateCbirtharea()
+	})
+}
+
+// SetCidcardNo sets the "cidcard_no" field.
+func (u *ContactUpsertOne) SetCidcardNo(v string) *ContactUpsertOne {
+	return u.Update(func(s *ContactUpsert) {
+		s.SetCidcardNo(v)
+	})
+}
+
+// UpdateCidcardNo sets the "cidcard_no" field to the value that was provided on create.
+func (u *ContactUpsertOne) UpdateCidcardNo() *ContactUpsertOne {
+	return u.Update(func(s *ContactUpsert) {
+		s.UpdateCidcardNo()
+	})
+}
+
+// SetCtitle sets the "ctitle" field.
+func (u *ContactUpsertOne) SetCtitle(v string) *ContactUpsertOne {
+	return u.Update(func(s *ContactUpsert) {
+		s.SetCtitle(v)
+	})
+}
+
+// UpdateCtitle sets the "ctitle" field to the value that was provided on create.
+func (u *ContactUpsertOne) UpdateCtitle() *ContactUpsertOne {
+	return u.Update(func(s *ContactUpsert) {
+		s.UpdateCtitle()
+	})
+}
+
+// SetCc sets the "cc" field.
+func (u *ContactUpsertOne) SetCc(v string) *ContactUpsertOne {
+	return u.Update(func(s *ContactUpsert) {
+		s.SetCc(v)
+	})
+}
+
+// UpdateCc sets the "cc" field to the value that was provided on create.
+func (u *ContactUpsertOne) UpdateCc() *ContactUpsertOne {
+	return u.Update(func(s *ContactUpsert) {
+		s.UpdateCc()
+	})
+}
+
+// SetPhone sets the "phone" field.
+func (u *ContactUpsertOne) SetPhone(v string) *ContactUpsertOne {
+	return u.Update(func(s *ContactUpsert) {
+		s.SetPhone(v)
+	})
+}
+
+// UpdatePhone sets the "phone" field to the value that was provided on create.
+func (u *ContactUpsertOne) UpdatePhone() *ContactUpsertOne {
+	return u.Update(func(s *ContactUpsert) {
+		s.UpdatePhone()
+	})
+}
+
 // Exec executes the query.
 func (u *ContactUpsertOne) Exec(ctx context.Context) error {
 	if len(u.create.conflict) == 0 {
@@ -1937,6 +2588,195 @@ func (u *ContactUpsertBulk) ClearOrganizationID() *ContactUpsertBulk {
 	})
 }
 
+// SetCtype sets the "ctype" field.
+func (u *ContactUpsertBulk) SetCtype(v uint64) *ContactUpsertBulk {
+	return u.Update(func(s *ContactUpsert) {
+		s.SetCtype(v)
+	})
+}
+
+// AddCtype adds v to the "ctype" field.
+func (u *ContactUpsertBulk) AddCtype(v uint64) *ContactUpsertBulk {
+	return u.Update(func(s *ContactUpsert) {
+		s.AddCtype(v)
+	})
+}
+
+// UpdateCtype sets the "ctype" field to the value that was provided on create.
+func (u *ContactUpsertBulk) UpdateCtype() *ContactUpsertBulk {
+	return u.Update(func(s *ContactUpsert) {
+		s.UpdateCtype()
+	})
+}
+
+// SetCsex sets the "csex" field.
+func (u *ContactUpsertBulk) SetCsex(v int) *ContactUpsertBulk {
+	return u.Update(func(s *ContactUpsert) {
+		s.SetCsex(v)
+	})
+}
+
+// AddCsex adds v to the "csex" field.
+func (u *ContactUpsertBulk) AddCsex(v int) *ContactUpsertBulk {
+	return u.Update(func(s *ContactUpsert) {
+		s.AddCsex(v)
+	})
+}
+
+// UpdateCsex sets the "csex" field to the value that was provided on create.
+func (u *ContactUpsertBulk) UpdateCsex() *ContactUpsertBulk {
+	return u.Update(func(s *ContactUpsert) {
+		s.UpdateCsex()
+	})
+}
+
+// SetCage sets the "cage" field.
+func (u *ContactUpsertBulk) SetCage(v int) *ContactUpsertBulk {
+	return u.Update(func(s *ContactUpsert) {
+		s.SetCage(v)
+	})
+}
+
+// AddCage adds v to the "cage" field.
+func (u *ContactUpsertBulk) AddCage(v int) *ContactUpsertBulk {
+	return u.Update(func(s *ContactUpsert) {
+		s.AddCage(v)
+	})
+}
+
+// UpdateCage sets the "cage" field to the value that was provided on create.
+func (u *ContactUpsertBulk) UpdateCage() *ContactUpsertBulk {
+	return u.Update(func(s *ContactUpsert) {
+		s.UpdateCage()
+	})
+}
+
+// SetCname sets the "cname" field.
+func (u *ContactUpsertBulk) SetCname(v string) *ContactUpsertBulk {
+	return u.Update(func(s *ContactUpsert) {
+		s.SetCname(v)
+	})
+}
+
+// UpdateCname sets the "cname" field to the value that was provided on create.
+func (u *ContactUpsertBulk) UpdateCname() *ContactUpsertBulk {
+	return u.Update(func(s *ContactUpsert) {
+		s.UpdateCname()
+	})
+}
+
+// SetCarea sets the "carea" field.
+func (u *ContactUpsertBulk) SetCarea(v string) *ContactUpsertBulk {
+	return u.Update(func(s *ContactUpsert) {
+		s.SetCarea(v)
+	})
+}
+
+// UpdateCarea sets the "carea" field to the value that was provided on create.
+func (u *ContactUpsertBulk) UpdateCarea() *ContactUpsertBulk {
+	return u.Update(func(s *ContactUpsert) {
+		s.UpdateCarea()
+	})
+}
+
+// SetCmobile sets the "cmobile" field.
+func (u *ContactUpsertBulk) SetCmobile(v string) *ContactUpsertBulk {
+	return u.Update(func(s *ContactUpsert) {
+		s.SetCmobile(v)
+	})
+}
+
+// UpdateCmobile sets the "cmobile" field to the value that was provided on create.
+func (u *ContactUpsertBulk) UpdateCmobile() *ContactUpsertBulk {
+	return u.Update(func(s *ContactUpsert) {
+		s.UpdateCmobile()
+	})
+}
+
+// SetCbirthday sets the "cbirthday" field.
+func (u *ContactUpsertBulk) SetCbirthday(v string) *ContactUpsertBulk {
+	return u.Update(func(s *ContactUpsert) {
+		s.SetCbirthday(v)
+	})
+}
+
+// UpdateCbirthday sets the "cbirthday" field to the value that was provided on create.
+func (u *ContactUpsertBulk) UpdateCbirthday() *ContactUpsertBulk {
+	return u.Update(func(s *ContactUpsert) {
+		s.UpdateCbirthday()
+	})
+}
+
+// SetCbirtharea sets the "cbirtharea" field.
+func (u *ContactUpsertBulk) SetCbirtharea(v string) *ContactUpsertBulk {
+	return u.Update(func(s *ContactUpsert) {
+		s.SetCbirtharea(v)
+	})
+}
+
+// UpdateCbirtharea sets the "cbirtharea" field to the value that was provided on create.
+func (u *ContactUpsertBulk) UpdateCbirtharea() *ContactUpsertBulk {
+	return u.Update(func(s *ContactUpsert) {
+		s.UpdateCbirtharea()
+	})
+}
+
+// SetCidcardNo sets the "cidcard_no" field.
+func (u *ContactUpsertBulk) SetCidcardNo(v string) *ContactUpsertBulk {
+	return u.Update(func(s *ContactUpsert) {
+		s.SetCidcardNo(v)
+	})
+}
+
+// UpdateCidcardNo sets the "cidcard_no" field to the value that was provided on create.
+func (u *ContactUpsertBulk) UpdateCidcardNo() *ContactUpsertBulk {
+	return u.Update(func(s *ContactUpsert) {
+		s.UpdateCidcardNo()
+	})
+}
+
+// SetCtitle sets the "ctitle" field.
+func (u *ContactUpsertBulk) SetCtitle(v string) *ContactUpsertBulk {
+	return u.Update(func(s *ContactUpsert) {
+		s.SetCtitle(v)
+	})
+}
+
+// UpdateCtitle sets the "ctitle" field to the value that was provided on create.
+func (u *ContactUpsertBulk) UpdateCtitle() *ContactUpsertBulk {
+	return u.Update(func(s *ContactUpsert) {
+		s.UpdateCtitle()
+	})
+}
+
+// SetCc sets the "cc" field.
+func (u *ContactUpsertBulk) SetCc(v string) *ContactUpsertBulk {
+	return u.Update(func(s *ContactUpsert) {
+		s.SetCc(v)
+	})
+}
+
+// UpdateCc sets the "cc" field to the value that was provided on create.
+func (u *ContactUpsertBulk) UpdateCc() *ContactUpsertBulk {
+	return u.Update(func(s *ContactUpsert) {
+		s.UpdateCc()
+	})
+}
+
+// SetPhone sets the "phone" field.
+func (u *ContactUpsertBulk) SetPhone(v string) *ContactUpsertBulk {
+	return u.Update(func(s *ContactUpsert) {
+		s.SetPhone(v)
+	})
+}
+
+// UpdatePhone sets the "phone" field to the value that was provided on create.
+func (u *ContactUpsertBulk) UpdatePhone() *ContactUpsertBulk {
+	return u.Update(func(s *ContactUpsert) {
+		s.UpdatePhone()
+	})
+}
+
 // Exec executes the query.
 func (u *ContactUpsertBulk) Exec(ctx context.Context) error {
 	if u.create.err != nil {

+ 468 - 0
ent/contact_update.go

@@ -354,6 +354,195 @@ func (cu *ContactUpdate) ClearOrganizationID() *ContactUpdate {
 	return cu
 }
 
+// SetCtype sets the "ctype" field.
+func (cu *ContactUpdate) SetCtype(u uint64) *ContactUpdate {
+	cu.mutation.ResetCtype()
+	cu.mutation.SetCtype(u)
+	return cu
+}
+
+// SetNillableCtype sets the "ctype" field if the given value is not nil.
+func (cu *ContactUpdate) SetNillableCtype(u *uint64) *ContactUpdate {
+	if u != nil {
+		cu.SetCtype(*u)
+	}
+	return cu
+}
+
+// AddCtype adds u to the "ctype" field.
+func (cu *ContactUpdate) AddCtype(u int64) *ContactUpdate {
+	cu.mutation.AddCtype(u)
+	return cu
+}
+
+// SetCsex sets the "csex" field.
+func (cu *ContactUpdate) SetCsex(i int) *ContactUpdate {
+	cu.mutation.ResetCsex()
+	cu.mutation.SetCsex(i)
+	return cu
+}
+
+// SetNillableCsex sets the "csex" field if the given value is not nil.
+func (cu *ContactUpdate) SetNillableCsex(i *int) *ContactUpdate {
+	if i != nil {
+		cu.SetCsex(*i)
+	}
+	return cu
+}
+
+// AddCsex adds i to the "csex" field.
+func (cu *ContactUpdate) AddCsex(i int) *ContactUpdate {
+	cu.mutation.AddCsex(i)
+	return cu
+}
+
+// SetCage sets the "cage" field.
+func (cu *ContactUpdate) SetCage(i int) *ContactUpdate {
+	cu.mutation.ResetCage()
+	cu.mutation.SetCage(i)
+	return cu
+}
+
+// SetNillableCage sets the "cage" field if the given value is not nil.
+func (cu *ContactUpdate) SetNillableCage(i *int) *ContactUpdate {
+	if i != nil {
+		cu.SetCage(*i)
+	}
+	return cu
+}
+
+// AddCage adds i to the "cage" field.
+func (cu *ContactUpdate) AddCage(i int) *ContactUpdate {
+	cu.mutation.AddCage(i)
+	return cu
+}
+
+// SetCname sets the "cname" field.
+func (cu *ContactUpdate) SetCname(s string) *ContactUpdate {
+	cu.mutation.SetCname(s)
+	return cu
+}
+
+// SetNillableCname sets the "cname" field if the given value is not nil.
+func (cu *ContactUpdate) SetNillableCname(s *string) *ContactUpdate {
+	if s != nil {
+		cu.SetCname(*s)
+	}
+	return cu
+}
+
+// SetCarea sets the "carea" field.
+func (cu *ContactUpdate) SetCarea(s string) *ContactUpdate {
+	cu.mutation.SetCarea(s)
+	return cu
+}
+
+// SetNillableCarea sets the "carea" field if the given value is not nil.
+func (cu *ContactUpdate) SetNillableCarea(s *string) *ContactUpdate {
+	if s != nil {
+		cu.SetCarea(*s)
+	}
+	return cu
+}
+
+// SetCmobile sets the "cmobile" field.
+func (cu *ContactUpdate) SetCmobile(s string) *ContactUpdate {
+	cu.mutation.SetCmobile(s)
+	return cu
+}
+
+// SetNillableCmobile sets the "cmobile" field if the given value is not nil.
+func (cu *ContactUpdate) SetNillableCmobile(s *string) *ContactUpdate {
+	if s != nil {
+		cu.SetCmobile(*s)
+	}
+	return cu
+}
+
+// SetCbirthday sets the "cbirthday" field.
+func (cu *ContactUpdate) SetCbirthday(s string) *ContactUpdate {
+	cu.mutation.SetCbirthday(s)
+	return cu
+}
+
+// SetNillableCbirthday sets the "cbirthday" field if the given value is not nil.
+func (cu *ContactUpdate) SetNillableCbirthday(s *string) *ContactUpdate {
+	if s != nil {
+		cu.SetCbirthday(*s)
+	}
+	return cu
+}
+
+// SetCbirtharea sets the "cbirtharea" field.
+func (cu *ContactUpdate) SetCbirtharea(s string) *ContactUpdate {
+	cu.mutation.SetCbirtharea(s)
+	return cu
+}
+
+// SetNillableCbirtharea sets the "cbirtharea" field if the given value is not nil.
+func (cu *ContactUpdate) SetNillableCbirtharea(s *string) *ContactUpdate {
+	if s != nil {
+		cu.SetCbirtharea(*s)
+	}
+	return cu
+}
+
+// SetCidcardNo sets the "cidcard_no" field.
+func (cu *ContactUpdate) SetCidcardNo(s string) *ContactUpdate {
+	cu.mutation.SetCidcardNo(s)
+	return cu
+}
+
+// SetNillableCidcardNo sets the "cidcard_no" field if the given value is not nil.
+func (cu *ContactUpdate) SetNillableCidcardNo(s *string) *ContactUpdate {
+	if s != nil {
+		cu.SetCidcardNo(*s)
+	}
+	return cu
+}
+
+// SetCtitle sets the "ctitle" field.
+func (cu *ContactUpdate) SetCtitle(s string) *ContactUpdate {
+	cu.mutation.SetCtitle(s)
+	return cu
+}
+
+// SetNillableCtitle sets the "ctitle" field if the given value is not nil.
+func (cu *ContactUpdate) SetNillableCtitle(s *string) *ContactUpdate {
+	if s != nil {
+		cu.SetCtitle(*s)
+	}
+	return cu
+}
+
+// SetCc sets the "cc" field.
+func (cu *ContactUpdate) SetCc(s string) *ContactUpdate {
+	cu.mutation.SetCc(s)
+	return cu
+}
+
+// SetNillableCc sets the "cc" field if the given value is not nil.
+func (cu *ContactUpdate) SetNillableCc(s *string) *ContactUpdate {
+	if s != nil {
+		cu.SetCc(*s)
+	}
+	return cu
+}
+
+// SetPhone sets the "phone" field.
+func (cu *ContactUpdate) SetPhone(s string) *ContactUpdate {
+	cu.mutation.SetPhone(s)
+	return cu
+}
+
+// SetNillablePhone sets the "phone" field if the given value is not nil.
+func (cu *ContactUpdate) SetNillablePhone(s *string) *ContactUpdate {
+	if s != nil {
+		cu.SetPhone(*s)
+	}
+	return cu
+}
+
 // AddContactRelationshipIDs adds the "contact_relationships" edge to the LabelRelationship entity by IDs.
 func (cu *ContactUpdate) AddContactRelationshipIDs(ids ...uint64) *ContactUpdate {
 	cu.mutation.AddContactRelationshipIDs(ids...)
@@ -569,6 +758,51 @@ func (cu *ContactUpdate) sqlSave(ctx context.Context) (n int, err error) {
 	if cu.mutation.OrganizationIDCleared() {
 		_spec.ClearField(contact.FieldOrganizationID, field.TypeUint64)
 	}
+	if value, ok := cu.mutation.Ctype(); ok {
+		_spec.SetField(contact.FieldCtype, field.TypeUint64, value)
+	}
+	if value, ok := cu.mutation.AddedCtype(); ok {
+		_spec.AddField(contact.FieldCtype, field.TypeUint64, value)
+	}
+	if value, ok := cu.mutation.Csex(); ok {
+		_spec.SetField(contact.FieldCsex, field.TypeInt, value)
+	}
+	if value, ok := cu.mutation.AddedCsex(); ok {
+		_spec.AddField(contact.FieldCsex, field.TypeInt, value)
+	}
+	if value, ok := cu.mutation.Cage(); ok {
+		_spec.SetField(contact.FieldCage, field.TypeInt, value)
+	}
+	if value, ok := cu.mutation.AddedCage(); ok {
+		_spec.AddField(contact.FieldCage, field.TypeInt, value)
+	}
+	if value, ok := cu.mutation.Cname(); ok {
+		_spec.SetField(contact.FieldCname, field.TypeString, value)
+	}
+	if value, ok := cu.mutation.Carea(); ok {
+		_spec.SetField(contact.FieldCarea, field.TypeString, value)
+	}
+	if value, ok := cu.mutation.Cmobile(); ok {
+		_spec.SetField(contact.FieldCmobile, field.TypeString, value)
+	}
+	if value, ok := cu.mutation.Cbirthday(); ok {
+		_spec.SetField(contact.FieldCbirthday, field.TypeString, value)
+	}
+	if value, ok := cu.mutation.Cbirtharea(); ok {
+		_spec.SetField(contact.FieldCbirtharea, field.TypeString, value)
+	}
+	if value, ok := cu.mutation.CidcardNo(); ok {
+		_spec.SetField(contact.FieldCidcardNo, field.TypeString, value)
+	}
+	if value, ok := cu.mutation.Ctitle(); ok {
+		_spec.SetField(contact.FieldCtitle, field.TypeString, value)
+	}
+	if value, ok := cu.mutation.Cc(); ok {
+		_spec.SetField(contact.FieldCc, field.TypeString, value)
+	}
+	if value, ok := cu.mutation.Phone(); ok {
+		_spec.SetField(contact.FieldPhone, field.TypeString, value)
+	}
 	if cu.mutation.ContactRelationshipsCleared() {
 		edge := &sqlgraph.EdgeSpec{
 			Rel:     sqlgraph.O2M,
@@ -1003,6 +1237,195 @@ func (cuo *ContactUpdateOne) ClearOrganizationID() *ContactUpdateOne {
 	return cuo
 }
 
+// SetCtype sets the "ctype" field.
+func (cuo *ContactUpdateOne) SetCtype(u uint64) *ContactUpdateOne {
+	cuo.mutation.ResetCtype()
+	cuo.mutation.SetCtype(u)
+	return cuo
+}
+
+// SetNillableCtype sets the "ctype" field if the given value is not nil.
+func (cuo *ContactUpdateOne) SetNillableCtype(u *uint64) *ContactUpdateOne {
+	if u != nil {
+		cuo.SetCtype(*u)
+	}
+	return cuo
+}
+
+// AddCtype adds u to the "ctype" field.
+func (cuo *ContactUpdateOne) AddCtype(u int64) *ContactUpdateOne {
+	cuo.mutation.AddCtype(u)
+	return cuo
+}
+
+// SetCsex sets the "csex" field.
+func (cuo *ContactUpdateOne) SetCsex(i int) *ContactUpdateOne {
+	cuo.mutation.ResetCsex()
+	cuo.mutation.SetCsex(i)
+	return cuo
+}
+
+// SetNillableCsex sets the "csex" field if the given value is not nil.
+func (cuo *ContactUpdateOne) SetNillableCsex(i *int) *ContactUpdateOne {
+	if i != nil {
+		cuo.SetCsex(*i)
+	}
+	return cuo
+}
+
+// AddCsex adds i to the "csex" field.
+func (cuo *ContactUpdateOne) AddCsex(i int) *ContactUpdateOne {
+	cuo.mutation.AddCsex(i)
+	return cuo
+}
+
+// SetCage sets the "cage" field.
+func (cuo *ContactUpdateOne) SetCage(i int) *ContactUpdateOne {
+	cuo.mutation.ResetCage()
+	cuo.mutation.SetCage(i)
+	return cuo
+}
+
+// SetNillableCage sets the "cage" field if the given value is not nil.
+func (cuo *ContactUpdateOne) SetNillableCage(i *int) *ContactUpdateOne {
+	if i != nil {
+		cuo.SetCage(*i)
+	}
+	return cuo
+}
+
+// AddCage adds i to the "cage" field.
+func (cuo *ContactUpdateOne) AddCage(i int) *ContactUpdateOne {
+	cuo.mutation.AddCage(i)
+	return cuo
+}
+
+// SetCname sets the "cname" field.
+func (cuo *ContactUpdateOne) SetCname(s string) *ContactUpdateOne {
+	cuo.mutation.SetCname(s)
+	return cuo
+}
+
+// SetNillableCname sets the "cname" field if the given value is not nil.
+func (cuo *ContactUpdateOne) SetNillableCname(s *string) *ContactUpdateOne {
+	if s != nil {
+		cuo.SetCname(*s)
+	}
+	return cuo
+}
+
+// SetCarea sets the "carea" field.
+func (cuo *ContactUpdateOne) SetCarea(s string) *ContactUpdateOne {
+	cuo.mutation.SetCarea(s)
+	return cuo
+}
+
+// SetNillableCarea sets the "carea" field if the given value is not nil.
+func (cuo *ContactUpdateOne) SetNillableCarea(s *string) *ContactUpdateOne {
+	if s != nil {
+		cuo.SetCarea(*s)
+	}
+	return cuo
+}
+
+// SetCmobile sets the "cmobile" field.
+func (cuo *ContactUpdateOne) SetCmobile(s string) *ContactUpdateOne {
+	cuo.mutation.SetCmobile(s)
+	return cuo
+}
+
+// SetNillableCmobile sets the "cmobile" field if the given value is not nil.
+func (cuo *ContactUpdateOne) SetNillableCmobile(s *string) *ContactUpdateOne {
+	if s != nil {
+		cuo.SetCmobile(*s)
+	}
+	return cuo
+}
+
+// SetCbirthday sets the "cbirthday" field.
+func (cuo *ContactUpdateOne) SetCbirthday(s string) *ContactUpdateOne {
+	cuo.mutation.SetCbirthday(s)
+	return cuo
+}
+
+// SetNillableCbirthday sets the "cbirthday" field if the given value is not nil.
+func (cuo *ContactUpdateOne) SetNillableCbirthday(s *string) *ContactUpdateOne {
+	if s != nil {
+		cuo.SetCbirthday(*s)
+	}
+	return cuo
+}
+
+// SetCbirtharea sets the "cbirtharea" field.
+func (cuo *ContactUpdateOne) SetCbirtharea(s string) *ContactUpdateOne {
+	cuo.mutation.SetCbirtharea(s)
+	return cuo
+}
+
+// SetNillableCbirtharea sets the "cbirtharea" field if the given value is not nil.
+func (cuo *ContactUpdateOne) SetNillableCbirtharea(s *string) *ContactUpdateOne {
+	if s != nil {
+		cuo.SetCbirtharea(*s)
+	}
+	return cuo
+}
+
+// SetCidcardNo sets the "cidcard_no" field.
+func (cuo *ContactUpdateOne) SetCidcardNo(s string) *ContactUpdateOne {
+	cuo.mutation.SetCidcardNo(s)
+	return cuo
+}
+
+// SetNillableCidcardNo sets the "cidcard_no" field if the given value is not nil.
+func (cuo *ContactUpdateOne) SetNillableCidcardNo(s *string) *ContactUpdateOne {
+	if s != nil {
+		cuo.SetCidcardNo(*s)
+	}
+	return cuo
+}
+
+// SetCtitle sets the "ctitle" field.
+func (cuo *ContactUpdateOne) SetCtitle(s string) *ContactUpdateOne {
+	cuo.mutation.SetCtitle(s)
+	return cuo
+}
+
+// SetNillableCtitle sets the "ctitle" field if the given value is not nil.
+func (cuo *ContactUpdateOne) SetNillableCtitle(s *string) *ContactUpdateOne {
+	if s != nil {
+		cuo.SetCtitle(*s)
+	}
+	return cuo
+}
+
+// SetCc sets the "cc" field.
+func (cuo *ContactUpdateOne) SetCc(s string) *ContactUpdateOne {
+	cuo.mutation.SetCc(s)
+	return cuo
+}
+
+// SetNillableCc sets the "cc" field if the given value is not nil.
+func (cuo *ContactUpdateOne) SetNillableCc(s *string) *ContactUpdateOne {
+	if s != nil {
+		cuo.SetCc(*s)
+	}
+	return cuo
+}
+
+// SetPhone sets the "phone" field.
+func (cuo *ContactUpdateOne) SetPhone(s string) *ContactUpdateOne {
+	cuo.mutation.SetPhone(s)
+	return cuo
+}
+
+// SetNillablePhone sets the "phone" field if the given value is not nil.
+func (cuo *ContactUpdateOne) SetNillablePhone(s *string) *ContactUpdateOne {
+	if s != nil {
+		cuo.SetPhone(*s)
+	}
+	return cuo
+}
+
 // AddContactRelationshipIDs adds the "contact_relationships" edge to the LabelRelationship entity by IDs.
 func (cuo *ContactUpdateOne) AddContactRelationshipIDs(ids ...uint64) *ContactUpdateOne {
 	cuo.mutation.AddContactRelationshipIDs(ids...)
@@ -1248,6 +1671,51 @@ func (cuo *ContactUpdateOne) sqlSave(ctx context.Context) (_node *Contact, err e
 	if cuo.mutation.OrganizationIDCleared() {
 		_spec.ClearField(contact.FieldOrganizationID, field.TypeUint64)
 	}
+	if value, ok := cuo.mutation.Ctype(); ok {
+		_spec.SetField(contact.FieldCtype, field.TypeUint64, value)
+	}
+	if value, ok := cuo.mutation.AddedCtype(); ok {
+		_spec.AddField(contact.FieldCtype, field.TypeUint64, value)
+	}
+	if value, ok := cuo.mutation.Csex(); ok {
+		_spec.SetField(contact.FieldCsex, field.TypeInt, value)
+	}
+	if value, ok := cuo.mutation.AddedCsex(); ok {
+		_spec.AddField(contact.FieldCsex, field.TypeInt, value)
+	}
+	if value, ok := cuo.mutation.Cage(); ok {
+		_spec.SetField(contact.FieldCage, field.TypeInt, value)
+	}
+	if value, ok := cuo.mutation.AddedCage(); ok {
+		_spec.AddField(contact.FieldCage, field.TypeInt, value)
+	}
+	if value, ok := cuo.mutation.Cname(); ok {
+		_spec.SetField(contact.FieldCname, field.TypeString, value)
+	}
+	if value, ok := cuo.mutation.Carea(); ok {
+		_spec.SetField(contact.FieldCarea, field.TypeString, value)
+	}
+	if value, ok := cuo.mutation.Cmobile(); ok {
+		_spec.SetField(contact.FieldCmobile, field.TypeString, value)
+	}
+	if value, ok := cuo.mutation.Cbirthday(); ok {
+		_spec.SetField(contact.FieldCbirthday, field.TypeString, value)
+	}
+	if value, ok := cuo.mutation.Cbirtharea(); ok {
+		_spec.SetField(contact.FieldCbirtharea, field.TypeString, value)
+	}
+	if value, ok := cuo.mutation.CidcardNo(); ok {
+		_spec.SetField(contact.FieldCidcardNo, field.TypeString, value)
+	}
+	if value, ok := cuo.mutation.Ctitle(); ok {
+		_spec.SetField(contact.FieldCtitle, field.TypeString, value)
+	}
+	if value, ok := cuo.mutation.Cc(); ok {
+		_spec.SetField(contact.FieldCc, field.TypeString, value)
+	}
+	if value, ok := cuo.mutation.Phone(); ok {
+		_spec.SetField(contact.FieldPhone, field.TypeString, value)
+	}
 	if cuo.mutation.ContactRelationshipsCleared() {
 		edge := &sqlgraph.EdgeSpec{
 			Rel:     sqlgraph.O2M,

+ 12 - 1
ent/label.go

@@ -35,6 +35,8 @@ type Label struct {
 	Conditions string `json:"conditions,omitempty"`
 	// 机构 ID
 	OrganizationID uint64 `json:"organization_id,omitempty"`
+	// 内容类型:1-微信 2-whatsapp
+	Ctype uint64 `json:"ctype,omitempty"`
 	// Edges holds the relations/edges for other nodes in the graph.
 	// The values are being populated by the LabelQuery when eager-loading is set.
 	Edges        LabelEdges `json:"edges"`
@@ -64,7 +66,7 @@ func (*Label) scanValues(columns []string) ([]any, error) {
 	values := make([]any, len(columns))
 	for i := range columns {
 		switch columns[i] {
-		case label.FieldID, label.FieldStatus, label.FieldType, label.FieldFrom, label.FieldMode, label.FieldOrganizationID:
+		case label.FieldID, label.FieldStatus, label.FieldType, label.FieldFrom, label.FieldMode, label.FieldOrganizationID, label.FieldCtype:
 			values[i] = new(sql.NullInt64)
 		case label.FieldName, label.FieldConditions:
 			values[i] = new(sql.NullString)
@@ -145,6 +147,12 @@ func (l *Label) assignValues(columns []string, values []any) error {
 			} else if value.Valid {
 				l.OrganizationID = uint64(value.Int64)
 			}
+		case label.FieldCtype:
+			if value, ok := values[i].(*sql.NullInt64); !ok {
+				return fmt.Errorf("unexpected type %T for field ctype", values[i])
+			} else if value.Valid {
+				l.Ctype = uint64(value.Int64)
+			}
 		default:
 			l.selectValues.Set(columns[i], values[i])
 		}
@@ -212,6 +220,9 @@ func (l *Label) String() string {
 	builder.WriteString(", ")
 	builder.WriteString("organization_id=")
 	builder.WriteString(fmt.Sprintf("%v", l.OrganizationID))
+	builder.WriteString(", ")
+	builder.WriteString("ctype=")
+	builder.WriteString(fmt.Sprintf("%v", l.Ctype))
 	builder.WriteByte(')')
 	return builder.String()
 }

+ 10 - 0
ent/label/label.go

@@ -32,6 +32,8 @@ const (
 	FieldConditions = "conditions"
 	// FieldOrganizationID holds the string denoting the organization_id field in the database.
 	FieldOrganizationID = "organization_id"
+	// FieldCtype holds the string denoting the ctype field in the database.
+	FieldCtype = "ctype"
 	// 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.
@@ -57,6 +59,7 @@ var Columns = []string{
 	FieldMode,
 	FieldConditions,
 	FieldOrganizationID,
+	FieldCtype,
 }
 
 // ValidColumn reports if the column name is valid (part of the table columns).
@@ -90,6 +93,8 @@ var (
 	DefaultConditions string
 	// DefaultOrganizationID holds the default value on creation for the "organization_id" field.
 	DefaultOrganizationID uint64
+	// DefaultCtype holds the default value on creation for the "ctype" field.
+	DefaultCtype uint64
 )
 
 // OrderOption defines the ordering options for the Label queries.
@@ -145,6 +150,11 @@ func ByOrganizationID(opts ...sql.OrderTermOption) OrderOption {
 	return sql.OrderByField(FieldOrganizationID, opts...).ToFunc()
 }
 
+// ByCtype orders the results by the ctype field.
+func ByCtype(opts ...sql.OrderTermOption) OrderOption {
+	return sql.OrderByField(FieldCtype, opts...).ToFunc()
+}
+
 // ByLabelRelationshipsCount orders the results by label_relationships count.
 func ByLabelRelationshipsCount(opts ...sql.OrderTermOption) OrderOption {
 	return func(s *sql.Selector) {

+ 45 - 0
ent/label/where.go

@@ -100,6 +100,11 @@ func OrganizationID(v uint64) predicate.Label {
 	return predicate.Label(sql.FieldEQ(FieldOrganizationID, v))
 }
 
+// Ctype applies equality check predicate on the "ctype" field. It's identical to CtypeEQ.
+func Ctype(v uint64) predicate.Label {
+	return predicate.Label(sql.FieldEQ(FieldCtype, v))
+}
+
 // CreatedAtEQ applies the EQ predicate on the "created_at" field.
 func CreatedAtEQ(v time.Time) predicate.Label {
 	return predicate.Label(sql.FieldEQ(FieldCreatedAt, v))
@@ -540,6 +545,46 @@ func OrganizationIDNotNil() predicate.Label {
 	return predicate.Label(sql.FieldNotNull(FieldOrganizationID))
 }
 
+// CtypeEQ applies the EQ predicate on the "ctype" field.
+func CtypeEQ(v uint64) predicate.Label {
+	return predicate.Label(sql.FieldEQ(FieldCtype, v))
+}
+
+// CtypeNEQ applies the NEQ predicate on the "ctype" field.
+func CtypeNEQ(v uint64) predicate.Label {
+	return predicate.Label(sql.FieldNEQ(FieldCtype, v))
+}
+
+// CtypeIn applies the In predicate on the "ctype" field.
+func CtypeIn(vs ...uint64) predicate.Label {
+	return predicate.Label(sql.FieldIn(FieldCtype, vs...))
+}
+
+// CtypeNotIn applies the NotIn predicate on the "ctype" field.
+func CtypeNotIn(vs ...uint64) predicate.Label {
+	return predicate.Label(sql.FieldNotIn(FieldCtype, vs...))
+}
+
+// CtypeGT applies the GT predicate on the "ctype" field.
+func CtypeGT(v uint64) predicate.Label {
+	return predicate.Label(sql.FieldGT(FieldCtype, v))
+}
+
+// CtypeGTE applies the GTE predicate on the "ctype" field.
+func CtypeGTE(v uint64) predicate.Label {
+	return predicate.Label(sql.FieldGTE(FieldCtype, v))
+}
+
+// CtypeLT applies the LT predicate on the "ctype" field.
+func CtypeLT(v uint64) predicate.Label {
+	return predicate.Label(sql.FieldLT(FieldCtype, v))
+}
+
+// CtypeLTE applies the LTE predicate on the "ctype" field.
+func CtypeLTE(v uint64) predicate.Label {
+	return predicate.Label(sql.FieldLTE(FieldCtype, v))
+}
+
 // HasLabelRelationships applies the HasEdge predicate on the "label_relationships" edge.
 func HasLabelRelationships() predicate.Label {
 	return predicate.Label(func(s *sql.Selector) {

+ 85 - 0
ent/label_create.go

@@ -149,6 +149,20 @@ func (lc *LabelCreate) SetNillableOrganizationID(u *uint64) *LabelCreate {
 	return lc
 }
 
+// SetCtype sets the "ctype" field.
+func (lc *LabelCreate) SetCtype(u uint64) *LabelCreate {
+	lc.mutation.SetCtype(u)
+	return lc
+}
+
+// SetNillableCtype sets the "ctype" field if the given value is not nil.
+func (lc *LabelCreate) SetNillableCtype(u *uint64) *LabelCreate {
+	if u != nil {
+		lc.SetCtype(*u)
+	}
+	return lc
+}
+
 // SetID sets the "id" field.
 func (lc *LabelCreate) SetID(u uint64) *LabelCreate {
 	lc.mutation.SetID(u)
@@ -241,6 +255,10 @@ func (lc *LabelCreate) defaults() {
 		v := label.DefaultOrganizationID
 		lc.mutation.SetOrganizationID(v)
 	}
+	if _, ok := lc.mutation.Ctype(); !ok {
+		v := label.DefaultCtype
+		lc.mutation.SetCtype(v)
+	}
 }
 
 // check runs all checks and user-defined validators on the builder.
@@ -263,6 +281,9 @@ func (lc *LabelCreate) check() error {
 	if _, ok := lc.mutation.Mode(); !ok {
 		return &ValidationError{Name: "mode", err: errors.New(`ent: missing required field "Label.mode"`)}
 	}
+	if _, ok := lc.mutation.Ctype(); !ok {
+		return &ValidationError{Name: "ctype", err: errors.New(`ent: missing required field "Label.ctype"`)}
+	}
 	return nil
 }
 
@@ -332,6 +353,10 @@ func (lc *LabelCreate) createSpec() (*Label, *sqlgraph.CreateSpec) {
 		_spec.SetField(label.FieldOrganizationID, field.TypeUint64, value)
 		_node.OrganizationID = value
 	}
+	if value, ok := lc.mutation.Ctype(); ok {
+		_spec.SetField(label.FieldCtype, field.TypeUint64, value)
+		_node.Ctype = value
+	}
 	if nodes := lc.mutation.LabelRelationshipsIDs(); len(nodes) > 0 {
 		edge := &sqlgraph.EdgeSpec{
 			Rel:     sqlgraph.O2M,
@@ -544,6 +569,24 @@ func (u *LabelUpsert) ClearOrganizationID() *LabelUpsert {
 	return u
 }
 
+// SetCtype sets the "ctype" field.
+func (u *LabelUpsert) SetCtype(v uint64) *LabelUpsert {
+	u.Set(label.FieldCtype, v)
+	return u
+}
+
+// UpdateCtype sets the "ctype" field to the value that was provided on create.
+func (u *LabelUpsert) UpdateCtype() *LabelUpsert {
+	u.SetExcluded(label.FieldCtype)
+	return u
+}
+
+// AddCtype adds v to the "ctype" field.
+func (u *LabelUpsert) AddCtype(v uint64) *LabelUpsert {
+	u.Add(label.FieldCtype, v)
+	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:
 //
@@ -763,6 +806,27 @@ func (u *LabelUpsertOne) ClearOrganizationID() *LabelUpsertOne {
 	})
 }
 
+// SetCtype sets the "ctype" field.
+func (u *LabelUpsertOne) SetCtype(v uint64) *LabelUpsertOne {
+	return u.Update(func(s *LabelUpsert) {
+		s.SetCtype(v)
+	})
+}
+
+// AddCtype adds v to the "ctype" field.
+func (u *LabelUpsertOne) AddCtype(v uint64) *LabelUpsertOne {
+	return u.Update(func(s *LabelUpsert) {
+		s.AddCtype(v)
+	})
+}
+
+// UpdateCtype sets the "ctype" field to the value that was provided on create.
+func (u *LabelUpsertOne) UpdateCtype() *LabelUpsertOne {
+	return u.Update(func(s *LabelUpsert) {
+		s.UpdateCtype()
+	})
+}
+
 // Exec executes the query.
 func (u *LabelUpsertOne) Exec(ctx context.Context) error {
 	if len(u.create.conflict) == 0 {
@@ -1148,6 +1212,27 @@ func (u *LabelUpsertBulk) ClearOrganizationID() *LabelUpsertBulk {
 	})
 }
 
+// SetCtype sets the "ctype" field.
+func (u *LabelUpsertBulk) SetCtype(v uint64) *LabelUpsertBulk {
+	return u.Update(func(s *LabelUpsert) {
+		s.SetCtype(v)
+	})
+}
+
+// AddCtype adds v to the "ctype" field.
+func (u *LabelUpsertBulk) AddCtype(v uint64) *LabelUpsertBulk {
+	return u.Update(func(s *LabelUpsert) {
+		s.AddCtype(v)
+	})
+}
+
+// UpdateCtype sets the "ctype" field to the value that was provided on create.
+func (u *LabelUpsertBulk) UpdateCtype() *LabelUpsertBulk {
+	return u.Update(func(s *LabelUpsert) {
+		s.UpdateCtype()
+	})
+}
+
 // Exec executes the query.
 func (u *LabelUpsertBulk) Exec(ctx context.Context) error {
 	if u.create.err != nil {

+ 54 - 0
ent/label_update.go

@@ -186,6 +186,27 @@ func (lu *LabelUpdate) ClearOrganizationID() *LabelUpdate {
 	return lu
 }
 
+// SetCtype sets the "ctype" field.
+func (lu *LabelUpdate) SetCtype(u uint64) *LabelUpdate {
+	lu.mutation.ResetCtype()
+	lu.mutation.SetCtype(u)
+	return lu
+}
+
+// SetNillableCtype sets the "ctype" field if the given value is not nil.
+func (lu *LabelUpdate) SetNillableCtype(u *uint64) *LabelUpdate {
+	if u != nil {
+		lu.SetCtype(*u)
+	}
+	return lu
+}
+
+// AddCtype adds u to the "ctype" field.
+func (lu *LabelUpdate) AddCtype(u int64) *LabelUpdate {
+	lu.mutation.AddCtype(u)
+	return lu
+}
+
 // AddLabelRelationshipIDs adds the "label_relationships" edge to the LabelRelationship entity by IDs.
 func (lu *LabelUpdate) AddLabelRelationshipIDs(ids ...uint64) *LabelUpdate {
 	lu.mutation.AddLabelRelationshipIDs(ids...)
@@ -320,6 +341,12 @@ func (lu *LabelUpdate) sqlSave(ctx context.Context) (n int, err error) {
 	if lu.mutation.OrganizationIDCleared() {
 		_spec.ClearField(label.FieldOrganizationID, field.TypeUint64)
 	}
+	if value, ok := lu.mutation.Ctype(); ok {
+		_spec.SetField(label.FieldCtype, field.TypeUint64, value)
+	}
+	if value, ok := lu.mutation.AddedCtype(); ok {
+		_spec.AddField(label.FieldCtype, field.TypeUint64, value)
+	}
 	if lu.mutation.LabelRelationshipsCleared() {
 		edge := &sqlgraph.EdgeSpec{
 			Rel:     sqlgraph.O2M,
@@ -542,6 +569,27 @@ func (luo *LabelUpdateOne) ClearOrganizationID() *LabelUpdateOne {
 	return luo
 }
 
+// SetCtype sets the "ctype" field.
+func (luo *LabelUpdateOne) SetCtype(u uint64) *LabelUpdateOne {
+	luo.mutation.ResetCtype()
+	luo.mutation.SetCtype(u)
+	return luo
+}
+
+// SetNillableCtype sets the "ctype" field if the given value is not nil.
+func (luo *LabelUpdateOne) SetNillableCtype(u *uint64) *LabelUpdateOne {
+	if u != nil {
+		luo.SetCtype(*u)
+	}
+	return luo
+}
+
+// AddCtype adds u to the "ctype" field.
+func (luo *LabelUpdateOne) AddCtype(u int64) *LabelUpdateOne {
+	luo.mutation.AddCtype(u)
+	return luo
+}
+
 // AddLabelRelationshipIDs adds the "label_relationships" edge to the LabelRelationship entity by IDs.
 func (luo *LabelUpdateOne) AddLabelRelationshipIDs(ids ...uint64) *LabelUpdateOne {
 	luo.mutation.AddLabelRelationshipIDs(ids...)
@@ -706,6 +754,12 @@ func (luo *LabelUpdateOne) sqlSave(ctx context.Context) (_node *Label, err error
 	if luo.mutation.OrganizationIDCleared() {
 		_spec.ClearField(label.FieldOrganizationID, field.TypeUint64)
 	}
+	if value, ok := luo.mutation.Ctype(); ok {
+		_spec.SetField(label.FieldCtype, field.TypeUint64, value)
+	}
+	if value, ok := luo.mutation.AddedCtype(); ok {
+		_spec.AddField(label.FieldCtype, field.TypeUint64, value)
+	}
 	if luo.mutation.LabelRelationshipsCleared() {
 		edge := &sqlgraph.EdgeSpec{
 			Rel:     sqlgraph.O2M,

+ 12 - 1
ent/labelrelationship.go

@@ -31,6 +31,8 @@ type LabelRelationship struct {
 	ContactID uint64 `json:"contact_id,omitempty"`
 	// 机构 ID
 	OrganizationID uint64 `json:"organization_id,omitempty"`
+	// 内容类型:1-微信 2-whatsapp
+	Ctype uint64 `json:"ctype,omitempty"`
 	// Edges holds the relations/edges for other nodes in the graph.
 	// The values are being populated by the LabelRelationshipQuery when eager-loading is set.
 	Edges        LabelRelationshipEdges `json:"edges"`
@@ -75,7 +77,7 @@ func (*LabelRelationship) scanValues(columns []string) ([]any, error) {
 	values := make([]any, len(columns))
 	for i := range columns {
 		switch columns[i] {
-		case labelrelationship.FieldID, labelrelationship.FieldStatus, labelrelationship.FieldLabelID, labelrelationship.FieldContactID, labelrelationship.FieldOrganizationID:
+		case labelrelationship.FieldID, labelrelationship.FieldStatus, labelrelationship.FieldLabelID, labelrelationship.FieldContactID, labelrelationship.FieldOrganizationID, labelrelationship.FieldCtype:
 			values[i] = new(sql.NullInt64)
 		case labelrelationship.FieldCreatedAt, labelrelationship.FieldUpdatedAt:
 			values[i] = new(sql.NullTime)
@@ -136,6 +138,12 @@ func (lr *LabelRelationship) assignValues(columns []string, values []any) error
 			} else if value.Valid {
 				lr.OrganizationID = uint64(value.Int64)
 			}
+		case labelrelationship.FieldCtype:
+			if value, ok := values[i].(*sql.NullInt64); !ok {
+				return fmt.Errorf("unexpected type %T for field ctype", values[i])
+			} else if value.Valid {
+				lr.Ctype = uint64(value.Int64)
+			}
 		default:
 			lr.selectValues.Set(columns[i], values[i])
 		}
@@ -199,6 +207,9 @@ func (lr *LabelRelationship) String() string {
 	builder.WriteString(", ")
 	builder.WriteString("organization_id=")
 	builder.WriteString(fmt.Sprintf("%v", lr.OrganizationID))
+	builder.WriteString(", ")
+	builder.WriteString("ctype=")
+	builder.WriteString(fmt.Sprintf("%v", lr.Ctype))
 	builder.WriteByte(')')
 	return builder.String()
 }

+ 10 - 0
ent/labelrelationship/labelrelationship.go

@@ -26,6 +26,8 @@ const (
 	FieldContactID = "contact_id"
 	// FieldOrganizationID holds the string denoting the organization_id field in the database.
 	FieldOrganizationID = "organization_id"
+	// FieldCtype holds the string denoting the ctype field in the database.
+	FieldCtype = "ctype"
 	// EdgeContacts holds the string denoting the contacts edge name in mutations.
 	EdgeContacts = "contacts"
 	// EdgeLabels holds the string denoting the labels edge name in mutations.
@@ -57,6 +59,7 @@ var Columns = []string{
 	FieldLabelID,
 	FieldContactID,
 	FieldOrganizationID,
+	FieldCtype,
 }
 
 // ValidColumn reports if the column name is valid (part of the table columns).
@@ -84,6 +87,8 @@ var (
 	DefaultContactID uint64
 	// DefaultOrganizationID holds the default value on creation for the "organization_id" field.
 	DefaultOrganizationID uint64
+	// DefaultCtype holds the default value on creation for the "ctype" field.
+	DefaultCtype uint64
 )
 
 // OrderOption defines the ordering options for the LabelRelationship queries.
@@ -124,6 +129,11 @@ func ByOrganizationID(opts ...sql.OrderTermOption) OrderOption {
 	return sql.OrderByField(FieldOrganizationID, opts...).ToFunc()
 }
 
+// ByCtype orders the results by the ctype field.
+func ByCtype(opts ...sql.OrderTermOption) OrderOption {
+	return sql.OrderByField(FieldCtype, opts...).ToFunc()
+}
+
 // ByContactsField orders the results by contacts field.
 func ByContactsField(field string, opts ...sql.OrderTermOption) OrderOption {
 	return func(s *sql.Selector) {

+ 45 - 0
ent/labelrelationship/where.go

@@ -85,6 +85,11 @@ func OrganizationID(v uint64) predicate.LabelRelationship {
 	return predicate.LabelRelationship(sql.FieldEQ(FieldOrganizationID, v))
 }
 
+// Ctype applies equality check predicate on the "ctype" field. It's identical to CtypeEQ.
+func Ctype(v uint64) predicate.LabelRelationship {
+	return predicate.LabelRelationship(sql.FieldEQ(FieldCtype, v))
+}
+
 // CreatedAtEQ applies the EQ predicate on the "created_at" field.
 func CreatedAtEQ(v time.Time) predicate.LabelRelationship {
 	return predicate.LabelRelationship(sql.FieldEQ(FieldCreatedAt, v))
@@ -305,6 +310,46 @@ func OrganizationIDNotNil() predicate.LabelRelationship {
 	return predicate.LabelRelationship(sql.FieldNotNull(FieldOrganizationID))
 }
 
+// CtypeEQ applies the EQ predicate on the "ctype" field.
+func CtypeEQ(v uint64) predicate.LabelRelationship {
+	return predicate.LabelRelationship(sql.FieldEQ(FieldCtype, v))
+}
+
+// CtypeNEQ applies the NEQ predicate on the "ctype" field.
+func CtypeNEQ(v uint64) predicate.LabelRelationship {
+	return predicate.LabelRelationship(sql.FieldNEQ(FieldCtype, v))
+}
+
+// CtypeIn applies the In predicate on the "ctype" field.
+func CtypeIn(vs ...uint64) predicate.LabelRelationship {
+	return predicate.LabelRelationship(sql.FieldIn(FieldCtype, vs...))
+}
+
+// CtypeNotIn applies the NotIn predicate on the "ctype" field.
+func CtypeNotIn(vs ...uint64) predicate.LabelRelationship {
+	return predicate.LabelRelationship(sql.FieldNotIn(FieldCtype, vs...))
+}
+
+// CtypeGT applies the GT predicate on the "ctype" field.
+func CtypeGT(v uint64) predicate.LabelRelationship {
+	return predicate.LabelRelationship(sql.FieldGT(FieldCtype, v))
+}
+
+// CtypeGTE applies the GTE predicate on the "ctype" field.
+func CtypeGTE(v uint64) predicate.LabelRelationship {
+	return predicate.LabelRelationship(sql.FieldGTE(FieldCtype, v))
+}
+
+// CtypeLT applies the LT predicate on the "ctype" field.
+func CtypeLT(v uint64) predicate.LabelRelationship {
+	return predicate.LabelRelationship(sql.FieldLT(FieldCtype, v))
+}
+
+// CtypeLTE applies the LTE predicate on the "ctype" field.
+func CtypeLTE(v uint64) predicate.LabelRelationship {
+	return predicate.LabelRelationship(sql.FieldLTE(FieldCtype, v))
+}
+
 // HasContacts applies the HasEdge predicate on the "contacts" edge.
 func HasContacts() predicate.LabelRelationship {
 	return predicate.LabelRelationship(func(s *sql.Selector) {

+ 85 - 0
ent/labelrelationship_create.go

@@ -108,6 +108,20 @@ func (lrc *LabelRelationshipCreate) SetNillableOrganizationID(u *uint64) *LabelR
 	return lrc
 }
 
+// SetCtype sets the "ctype" field.
+func (lrc *LabelRelationshipCreate) SetCtype(u uint64) *LabelRelationshipCreate {
+	lrc.mutation.SetCtype(u)
+	return lrc
+}
+
+// SetNillableCtype sets the "ctype" field if the given value is not nil.
+func (lrc *LabelRelationshipCreate) SetNillableCtype(u *uint64) *LabelRelationshipCreate {
+	if u != nil {
+		lrc.SetCtype(*u)
+	}
+	return lrc
+}
+
 // SetID sets the "id" field.
 func (lrc *LabelRelationshipCreate) SetID(u uint64) *LabelRelationshipCreate {
 	lrc.mutation.SetID(u)
@@ -195,6 +209,10 @@ func (lrc *LabelRelationshipCreate) defaults() {
 		v := labelrelationship.DefaultOrganizationID
 		lrc.mutation.SetOrganizationID(v)
 	}
+	if _, ok := lrc.mutation.Ctype(); !ok {
+		v := labelrelationship.DefaultCtype
+		lrc.mutation.SetCtype(v)
+	}
 }
 
 // check runs all checks and user-defined validators on the builder.
@@ -211,6 +229,9 @@ func (lrc *LabelRelationshipCreate) check() error {
 	if _, ok := lrc.mutation.ContactID(); !ok {
 		return &ValidationError{Name: "contact_id", err: errors.New(`ent: missing required field "LabelRelationship.contact_id"`)}
 	}
+	if _, ok := lrc.mutation.Ctype(); !ok {
+		return &ValidationError{Name: "ctype", err: errors.New(`ent: missing required field "LabelRelationship.ctype"`)}
+	}
 	if _, ok := lrc.mutation.ContactsID(); !ok {
 		return &ValidationError{Name: "contacts", err: errors.New(`ent: missing required edge "LabelRelationship.contacts"`)}
 	}
@@ -266,6 +287,10 @@ func (lrc *LabelRelationshipCreate) createSpec() (*LabelRelationship, *sqlgraph.
 		_spec.SetField(labelrelationship.FieldOrganizationID, field.TypeUint64, value)
 		_node.OrganizationID = value
 	}
+	if value, ok := lrc.mutation.Ctype(); ok {
+		_spec.SetField(labelrelationship.FieldCtype, field.TypeUint64, value)
+		_node.Ctype = value
+	}
 	if nodes := lrc.mutation.ContactsIDs(); len(nodes) > 0 {
 		edge := &sqlgraph.EdgeSpec{
 			Rel:     sqlgraph.M2O,
@@ -436,6 +461,24 @@ func (u *LabelRelationshipUpsert) ClearOrganizationID() *LabelRelationshipUpsert
 	return u
 }
 
+// SetCtype sets the "ctype" field.
+func (u *LabelRelationshipUpsert) SetCtype(v uint64) *LabelRelationshipUpsert {
+	u.Set(labelrelationship.FieldCtype, v)
+	return u
+}
+
+// UpdateCtype sets the "ctype" field to the value that was provided on create.
+func (u *LabelRelationshipUpsert) UpdateCtype() *LabelRelationshipUpsert {
+	u.SetExcluded(labelrelationship.FieldCtype)
+	return u
+}
+
+// AddCtype adds v to the "ctype" field.
+func (u *LabelRelationshipUpsert) AddCtype(v uint64) *LabelRelationshipUpsert {
+	u.Add(labelrelationship.FieldCtype, v)
+	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:
 //
@@ -585,6 +628,27 @@ func (u *LabelRelationshipUpsertOne) ClearOrganizationID() *LabelRelationshipUps
 	})
 }
 
+// SetCtype sets the "ctype" field.
+func (u *LabelRelationshipUpsertOne) SetCtype(v uint64) *LabelRelationshipUpsertOne {
+	return u.Update(func(s *LabelRelationshipUpsert) {
+		s.SetCtype(v)
+	})
+}
+
+// AddCtype adds v to the "ctype" field.
+func (u *LabelRelationshipUpsertOne) AddCtype(v uint64) *LabelRelationshipUpsertOne {
+	return u.Update(func(s *LabelRelationshipUpsert) {
+		s.AddCtype(v)
+	})
+}
+
+// UpdateCtype sets the "ctype" field to the value that was provided on create.
+func (u *LabelRelationshipUpsertOne) UpdateCtype() *LabelRelationshipUpsertOne {
+	return u.Update(func(s *LabelRelationshipUpsert) {
+		s.UpdateCtype()
+	})
+}
+
 // Exec executes the query.
 func (u *LabelRelationshipUpsertOne) Exec(ctx context.Context) error {
 	if len(u.create.conflict) == 0 {
@@ -900,6 +964,27 @@ func (u *LabelRelationshipUpsertBulk) ClearOrganizationID() *LabelRelationshipUp
 	})
 }
 
+// SetCtype sets the "ctype" field.
+func (u *LabelRelationshipUpsertBulk) SetCtype(v uint64) *LabelRelationshipUpsertBulk {
+	return u.Update(func(s *LabelRelationshipUpsert) {
+		s.SetCtype(v)
+	})
+}
+
+// AddCtype adds v to the "ctype" field.
+func (u *LabelRelationshipUpsertBulk) AddCtype(v uint64) *LabelRelationshipUpsertBulk {
+	return u.Update(func(s *LabelRelationshipUpsert) {
+		s.AddCtype(v)
+	})
+}
+
+// UpdateCtype sets the "ctype" field to the value that was provided on create.
+func (u *LabelRelationshipUpsertBulk) UpdateCtype() *LabelRelationshipUpsertBulk {
+	return u.Update(func(s *LabelRelationshipUpsert) {
+		s.UpdateCtype()
+	})
+}
+
 // Exec executes the query.
 func (u *LabelRelationshipUpsertBulk) Exec(ctx context.Context) error {
 	if u.create.err != nil {

+ 54 - 0
ent/labelrelationship_update.go

@@ -118,6 +118,27 @@ func (lru *LabelRelationshipUpdate) ClearOrganizationID() *LabelRelationshipUpda
 	return lru
 }
 
+// SetCtype sets the "ctype" field.
+func (lru *LabelRelationshipUpdate) SetCtype(u uint64) *LabelRelationshipUpdate {
+	lru.mutation.ResetCtype()
+	lru.mutation.SetCtype(u)
+	return lru
+}
+
+// SetNillableCtype sets the "ctype" field if the given value is not nil.
+func (lru *LabelRelationshipUpdate) SetNillableCtype(u *uint64) *LabelRelationshipUpdate {
+	if u != nil {
+		lru.SetCtype(*u)
+	}
+	return lru
+}
+
+// AddCtype adds u to the "ctype" field.
+func (lru *LabelRelationshipUpdate) AddCtype(u int64) *LabelRelationshipUpdate {
+	lru.mutation.AddCtype(u)
+	return lru
+}
+
 // SetContactsID sets the "contacts" edge to the Contact entity by ID.
 func (lru *LabelRelationshipUpdate) SetContactsID(id uint64) *LabelRelationshipUpdate {
 	lru.mutation.SetContactsID(id)
@@ -237,6 +258,12 @@ func (lru *LabelRelationshipUpdate) sqlSave(ctx context.Context) (n int, err err
 	if lru.mutation.OrganizationIDCleared() {
 		_spec.ClearField(labelrelationship.FieldOrganizationID, field.TypeUint64)
 	}
+	if value, ok := lru.mutation.Ctype(); ok {
+		_spec.SetField(labelrelationship.FieldCtype, field.TypeUint64, value)
+	}
+	if value, ok := lru.mutation.AddedCtype(); ok {
+		_spec.AddField(labelrelationship.FieldCtype, field.TypeUint64, value)
+	}
 	if lru.mutation.ContactsCleared() {
 		edge := &sqlgraph.EdgeSpec{
 			Rel:     sqlgraph.M2O,
@@ -403,6 +430,27 @@ func (lruo *LabelRelationshipUpdateOne) ClearOrganizationID() *LabelRelationship
 	return lruo
 }
 
+// SetCtype sets the "ctype" field.
+func (lruo *LabelRelationshipUpdateOne) SetCtype(u uint64) *LabelRelationshipUpdateOne {
+	lruo.mutation.ResetCtype()
+	lruo.mutation.SetCtype(u)
+	return lruo
+}
+
+// SetNillableCtype sets the "ctype" field if the given value is not nil.
+func (lruo *LabelRelationshipUpdateOne) SetNillableCtype(u *uint64) *LabelRelationshipUpdateOne {
+	if u != nil {
+		lruo.SetCtype(*u)
+	}
+	return lruo
+}
+
+// AddCtype adds u to the "ctype" field.
+func (lruo *LabelRelationshipUpdateOne) AddCtype(u int64) *LabelRelationshipUpdateOne {
+	lruo.mutation.AddCtype(u)
+	return lruo
+}
+
 // SetContactsID sets the "contacts" edge to the Contact entity by ID.
 func (lruo *LabelRelationshipUpdateOne) SetContactsID(id uint64) *LabelRelationshipUpdateOne {
 	lruo.mutation.SetContactsID(id)
@@ -552,6 +600,12 @@ func (lruo *LabelRelationshipUpdateOne) sqlSave(ctx context.Context) (_node *Lab
 	if lruo.mutation.OrganizationIDCleared() {
 		_spec.ClearField(labelrelationship.FieldOrganizationID, field.TypeUint64)
 	}
+	if value, ok := lruo.mutation.Ctype(); ok {
+		_spec.SetField(labelrelationship.FieldCtype, field.TypeUint64, value)
+	}
+	if value, ok := lruo.mutation.AddedCtype(); ok {
+		_spec.AddField(labelrelationship.FieldCtype, field.TypeUint64, value)
+	}
 	if lruo.mutation.ContactsCleared() {
 		edge := &sqlgraph.EdgeSpec{
 			Rel:     sqlgraph.M2O,

+ 19 - 4
ent/migrate/schema.go

@@ -135,6 +135,7 @@ var (
 		{Name: "send_time", Type: field.TypeTime, Nullable: true, Comment: "发送时间"},
 		{Name: "type", Type: field.TypeInt32, Nullable: true, Comment: "发送类型 1-群发消息 2-群发朋友圈"},
 		{Name: "organization_id", Type: field.TypeUint64, Comment: "organization_id | 租户ID"},
+		{Name: "ctype", Type: field.TypeUint64, Comment: "内容类型:1-微信 2-whatsapp", Default: 1},
 	}
 	// BatchMsgTable holds the schema information for the "batch_msg" table.
 	BatchMsgTable = &schema.Table{
@@ -254,6 +255,18 @@ var (
 		{Name: "gname", Type: field.TypeString, Comment: "群组名称", Default: ""},
 		{Name: "v3", Type: field.TypeString, Comment: "v3数据", Default: ""},
 		{Name: "organization_id", Type: field.TypeUint64, Nullable: true, Comment: "机构 ID", Default: 1},
+		{Name: "ctype", Type: field.TypeUint64, Comment: "内容类型:1-微信 2-whatsapp", Default: 1},
+		{Name: "csex", Type: field.TypeInt, Comment: "性别:1-男 2-女", Default: 0},
+		{Name: "cage", Type: field.TypeInt, Comment: "年龄", Default: 0},
+		{Name: "cname", Type: field.TypeString, Comment: "姓名", Default: ""},
+		{Name: "carea", Type: field.TypeString, Comment: "地区", Default: ""},
+		{Name: "cmobile", Type: field.TypeString, Comment: "手机号", Default: ""},
+		{Name: "cbirthday", Type: field.TypeString, Comment: "出生日期", Default: ""},
+		{Name: "cbirtharea", Type: field.TypeString, Comment: "出生地", Default: ""},
+		{Name: "cidcard_no", Type: field.TypeString, Comment: "身份证号", Default: ""},
+		{Name: "ctitle", Type: field.TypeString, Comment: "称呼", Default: ""},
+		{Name: "cc", Type: field.TypeString, Comment: "国家区号", Default: ""},
+		{Name: "phone", Type: field.TypeString, Comment: "手机号", Default: ""},
 	}
 	// ContactTable holds the schema information for the "contact" table.
 	ContactTable = &schema.Table{
@@ -417,6 +430,7 @@ var (
 		{Name: "mode", Type: field.TypeInt, Comment: "标签模式:1动态 2静态", Default: 1},
 		{Name: "conditions", Type: field.TypeString, Nullable: true, Comment: "标签的触达条件", Default: ""},
 		{Name: "organization_id", Type: field.TypeUint64, Nullable: true, Comment: "机构 ID", Default: 1},
+		{Name: "ctype", Type: field.TypeUint64, Comment: "内容类型:1-微信 2-whatsapp", Default: 1},
 	}
 	// LabelTable holds the schema information for the "label" table.
 	LabelTable = &schema.Table{
@@ -438,6 +452,7 @@ var (
 		{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: "organization_id", Type: field.TypeUint64, Nullable: true, Comment: "机构 ID", Default: 1},
+		{Name: "ctype", Type: field.TypeUint64, Comment: "内容类型:1-微信 2-whatsapp", Default: 1},
 		{Name: "contact_id", Type: field.TypeUint64, Comment: "联系人 ID", Default: 1},
 		{Name: "label_id", Type: field.TypeUint64, Comment: "标签 ID", Default: 1},
 	}
@@ -449,13 +464,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,
 			},
@@ -464,12 +479,12 @@ var (
 			{
 				Name:    "labelrelationship_label_id",
 				Unique:  false,
-				Columns: []*schema.Column{LabelRelationshipColumns[6]},
+				Columns: []*schema.Column{LabelRelationshipColumns[7]},
 			},
 			{
 				Name:    "labelrelationship_contact_id",
 				Unique:  false,
-				Columns: []*schema.Column{LabelRelationshipColumns[5]},
+				Columns: []*schema.Column{LabelRelationshipColumns[6]},
 			},
 		},
 	}

ファイルの差分が大きいため隠しています
+ 818 - 47
ent/mutation.go


+ 60 - 0
ent/runtime/runtime.go

@@ -217,6 +217,10 @@ func init() {
 	batchmsgDescOrganizationID := batchmsgFields[14].Descriptor()
 	// batchmsg.OrganizationIDValidator is a validator for the "organization_id" field. It is called by the builders before save.
 	batchmsg.OrganizationIDValidator = batchmsgDescOrganizationID.Validators[0].(func(uint64) error)
+	// batchmsgDescCtype is the schema descriptor for ctype field.
+	batchmsgDescCtype := batchmsgFields[15].Descriptor()
+	// batchmsg.DefaultCtype holds the default value on creation for the ctype field.
+	batchmsg.DefaultCtype = batchmsgDescCtype.Default.(uint64)
 	categoryMixin := schema.Category{}.Mixin()
 	categoryMixinHooks1 := categoryMixin[1].Hooks()
 	category.Hooks[0] = categoryMixinHooks1[0]
@@ -411,6 +415,54 @@ func init() {
 	contactDescOrganizationID := contactFields[15].Descriptor()
 	// contact.DefaultOrganizationID holds the default value on creation for the organization_id field.
 	contact.DefaultOrganizationID = contactDescOrganizationID.Default.(uint64)
+	// contactDescCtype is the schema descriptor for ctype field.
+	contactDescCtype := contactFields[16].Descriptor()
+	// contact.DefaultCtype holds the default value on creation for the ctype field.
+	contact.DefaultCtype = contactDescCtype.Default.(uint64)
+	// contactDescCsex is the schema descriptor for csex field.
+	contactDescCsex := contactFields[17].Descriptor()
+	// contact.DefaultCsex holds the default value on creation for the csex field.
+	contact.DefaultCsex = contactDescCsex.Default.(int)
+	// contactDescCage is the schema descriptor for cage field.
+	contactDescCage := contactFields[18].Descriptor()
+	// contact.DefaultCage holds the default value on creation for the cage field.
+	contact.DefaultCage = contactDescCage.Default.(int)
+	// contactDescCname is the schema descriptor for cname field.
+	contactDescCname := contactFields[19].Descriptor()
+	// contact.DefaultCname holds the default value on creation for the cname field.
+	contact.DefaultCname = contactDescCname.Default.(string)
+	// contactDescCarea is the schema descriptor for carea field.
+	contactDescCarea := contactFields[20].Descriptor()
+	// contact.DefaultCarea holds the default value on creation for the carea field.
+	contact.DefaultCarea = contactDescCarea.Default.(string)
+	// contactDescCmobile is the schema descriptor for cmobile field.
+	contactDescCmobile := contactFields[21].Descriptor()
+	// contact.DefaultCmobile holds the default value on creation for the cmobile field.
+	contact.DefaultCmobile = contactDescCmobile.Default.(string)
+	// contactDescCbirthday is the schema descriptor for cbirthday field.
+	contactDescCbirthday := contactFields[22].Descriptor()
+	// contact.DefaultCbirthday holds the default value on creation for the cbirthday field.
+	contact.DefaultCbirthday = contactDescCbirthday.Default.(string)
+	// contactDescCbirtharea is the schema descriptor for cbirtharea field.
+	contactDescCbirtharea := contactFields[23].Descriptor()
+	// contact.DefaultCbirtharea holds the default value on creation for the cbirtharea field.
+	contact.DefaultCbirtharea = contactDescCbirtharea.Default.(string)
+	// contactDescCidcardNo is the schema descriptor for cidcard_no field.
+	contactDescCidcardNo := contactFields[24].Descriptor()
+	// contact.DefaultCidcardNo holds the default value on creation for the cidcard_no field.
+	contact.DefaultCidcardNo = contactDescCidcardNo.Default.(string)
+	// contactDescCtitle is the schema descriptor for ctitle field.
+	contactDescCtitle := contactFields[25].Descriptor()
+	// contact.DefaultCtitle holds the default value on creation for the ctitle field.
+	contact.DefaultCtitle = contactDescCtitle.Default.(string)
+	// contactDescCc is the schema descriptor for cc field.
+	contactDescCc := contactFields[26].Descriptor()
+	// contact.DefaultCc holds the default value on creation for the cc field.
+	contact.DefaultCc = contactDescCc.Default.(string)
+	// contactDescPhone is the schema descriptor for phone field.
+	contactDescPhone := contactFields[27].Descriptor()
+	// contact.DefaultPhone holds the default value on creation for the phone field.
+	contact.DefaultPhone = contactDescPhone.Default.(string)
 	creditbalanceMixin := schema.CreditBalance{}.Mixin()
 	creditbalanceMixinHooks1 := creditbalanceMixin[1].Hooks()
 	creditbalance.Hooks[0] = creditbalanceMixinHooks1[0]
@@ -658,6 +710,10 @@ func init() {
 	labelDescOrganizationID := labelFields[5].Descriptor()
 	// label.DefaultOrganizationID holds the default value on creation for the organization_id field.
 	label.DefaultOrganizationID = labelDescOrganizationID.Default.(uint64)
+	// labelDescCtype is the schema descriptor for ctype field.
+	labelDescCtype := labelFields[6].Descriptor()
+	// label.DefaultCtype holds the default value on creation for the ctype field.
+	label.DefaultCtype = labelDescCtype.Default.(uint64)
 	labelrelationshipMixin := schema.LabelRelationship{}.Mixin()
 	labelrelationshipMixinFields0 := labelrelationshipMixin[0].Fields()
 	_ = labelrelationshipMixinFields0
@@ -691,6 +747,10 @@ func init() {
 	labelrelationshipDescOrganizationID := labelrelationshipFields[2].Descriptor()
 	// labelrelationship.DefaultOrganizationID holds the default value on creation for the organization_id field.
 	labelrelationship.DefaultOrganizationID = labelrelationshipDescOrganizationID.Default.(uint64)
+	// labelrelationshipDescCtype is the schema descriptor for ctype field.
+	labelrelationshipDescCtype := labelrelationshipFields[3].Descriptor()
+	// labelrelationship.DefaultCtype holds the default value on creation for the ctype field.
+	labelrelationship.DefaultCtype = labelrelationshipDescCtype.Default.(uint64)
 	labeltaggingMixin := schema.LabelTagging{}.Mixin()
 	labeltaggingMixinHooks2 := labeltaggingMixin[2].Hooks()
 	labeltagging.Hooks[0] = labeltaggingMixinHooks2[0]

+ 1 - 0
ent/schema/batch_msg.go

@@ -32,6 +32,7 @@ func (BatchMsg) Fields() []ent.Field {
 		field.Time("send_time").Optional().Comment("发送时间"),
 		field.Int32("type").Optional().Comment("发送类型 1-群发消息 2-群发朋友圈"),
 		field.Uint64("organization_id").Positive().Comment("organization_id | 租户ID"),
+		field.Uint64("ctype").Default(1).Comment("内容类型:1-微信 2-whatsapp"),
 	}
 }
 func (BatchMsg) Mixin() []ent.Mixin {

+ 12 - 0
ent/schema/contact.go

@@ -66,6 +66,18 @@ func (Contact) Fields() []ent.Field {
 		field.Uint64("organization_id").Optional().Default(1).
 			Comment("机构 ID").
 			Annotations(entsql.WithComments(true)),
+		field.Uint64("ctype").Default(1).Comment("内容类型:1-微信 2-whatsapp"),
+		field.Int("csex").Default(0).Comment("性别:1-男 2-女"),
+		field.Int("cage").Default(0).Comment("年龄"),
+		field.String("cname").Default("").Comment("姓名"),
+		field.String("carea").Default("").Comment("地区"),
+		field.String("cmobile").Default("").Comment("手机号"),
+		field.String("cbirthday").Default("").Comment("出生日期"),
+		field.String("cbirtharea").Default("").Comment("出生地"),
+		field.String("cidcard_no").Default("").Comment("身份证号"),
+		field.String("ctitle").Default("").Comment("称呼"),
+		field.String("cc").Default("").Comment("国家区号"),
+		field.String("phone").Default("").Comment("手机号"),
 	}
 }
 

+ 1 - 0
ent/schema/label.go

@@ -34,6 +34,7 @@ func (Label) Fields() []ent.Field {
 		field.Uint64("organization_id").Optional().Default(1).
 			Comment("机构 ID").
 			Annotations(entsql.WithComments(true)),
+		field.Uint64("ctype").Default(1).Comment("内容类型:1-微信 2-whatsapp"),
 	}
 }
 

+ 1 - 0
ent/schema/label_relationship.go

@@ -25,6 +25,7 @@ func (LabelRelationship) Fields() []ent.Field {
 		field.Uint64("organization_id").Optional().Default(1).
 			Comment("机构 ID").
 			Annotations(entsql.WithComments(true)),
+		field.Uint64("ctype").Default(1).Comment("内容类型:1-微信 2-whatsapp"),
 	}
 }
 

+ 360 - 0
ent/set_not_nil.go

@@ -1280,6 +1280,30 @@ func (bm *BatchMsgCreate) SetNotNilOrganizationID(value *uint64) *BatchMsgCreate
 }
 
 // set field if value's pointer is not nil.
+func (bm *BatchMsgUpdate) SetNotNilCtype(value *uint64) *BatchMsgUpdate {
+	if value != nil {
+		return bm.SetCtype(*value)
+	}
+	return bm
+}
+
+// set field if value's pointer is not nil.
+func (bm *BatchMsgUpdateOne) SetNotNilCtype(value *uint64) *BatchMsgUpdateOne {
+	if value != nil {
+		return bm.SetCtype(*value)
+	}
+	return bm
+}
+
+// set field if value's pointer is not nil.
+func (bm *BatchMsgCreate) SetNotNilCtype(value *uint64) *BatchMsgCreate {
+	if value != nil {
+		return bm.SetCtype(*value)
+	}
+	return bm
+}
+
+// set field if value's pointer is not nil.
 func (c *CategoryUpdate) SetNotNilUpdatedAt(value *time.Time) *CategoryUpdate {
 	if value != nil {
 		return c.SetUpdatedAt(*value)
@@ -2168,6 +2192,294 @@ func (c *ContactCreate) SetNotNilOrganizationID(value *uint64) *ContactCreate {
 }
 
 // set field if value's pointer is not nil.
+func (c *ContactUpdate) SetNotNilCtype(value *uint64) *ContactUpdate {
+	if value != nil {
+		return c.SetCtype(*value)
+	}
+	return c
+}
+
+// set field if value's pointer is not nil.
+func (c *ContactUpdateOne) SetNotNilCtype(value *uint64) *ContactUpdateOne {
+	if value != nil {
+		return c.SetCtype(*value)
+	}
+	return c
+}
+
+// set field if value's pointer is not nil.
+func (c *ContactCreate) SetNotNilCtype(value *uint64) *ContactCreate {
+	if value != nil {
+		return c.SetCtype(*value)
+	}
+	return c
+}
+
+// set field if value's pointer is not nil.
+func (c *ContactUpdate) SetNotNilCsex(value *int) *ContactUpdate {
+	if value != nil {
+		return c.SetCsex(*value)
+	}
+	return c
+}
+
+// set field if value's pointer is not nil.
+func (c *ContactUpdateOne) SetNotNilCsex(value *int) *ContactUpdateOne {
+	if value != nil {
+		return c.SetCsex(*value)
+	}
+	return c
+}
+
+// set field if value's pointer is not nil.
+func (c *ContactCreate) SetNotNilCsex(value *int) *ContactCreate {
+	if value != nil {
+		return c.SetCsex(*value)
+	}
+	return c
+}
+
+// set field if value's pointer is not nil.
+func (c *ContactUpdate) SetNotNilCage(value *int) *ContactUpdate {
+	if value != nil {
+		return c.SetCage(*value)
+	}
+	return c
+}
+
+// set field if value's pointer is not nil.
+func (c *ContactUpdateOne) SetNotNilCage(value *int) *ContactUpdateOne {
+	if value != nil {
+		return c.SetCage(*value)
+	}
+	return c
+}
+
+// set field if value's pointer is not nil.
+func (c *ContactCreate) SetNotNilCage(value *int) *ContactCreate {
+	if value != nil {
+		return c.SetCage(*value)
+	}
+	return c
+}
+
+// set field if value's pointer is not nil.
+func (c *ContactUpdate) SetNotNilCname(value *string) *ContactUpdate {
+	if value != nil {
+		return c.SetCname(*value)
+	}
+	return c
+}
+
+// set field if value's pointer is not nil.
+func (c *ContactUpdateOne) SetNotNilCname(value *string) *ContactUpdateOne {
+	if value != nil {
+		return c.SetCname(*value)
+	}
+	return c
+}
+
+// set field if value's pointer is not nil.
+func (c *ContactCreate) SetNotNilCname(value *string) *ContactCreate {
+	if value != nil {
+		return c.SetCname(*value)
+	}
+	return c
+}
+
+// set field if value's pointer is not nil.
+func (c *ContactUpdate) SetNotNilCarea(value *string) *ContactUpdate {
+	if value != nil {
+		return c.SetCarea(*value)
+	}
+	return c
+}
+
+// set field if value's pointer is not nil.
+func (c *ContactUpdateOne) SetNotNilCarea(value *string) *ContactUpdateOne {
+	if value != nil {
+		return c.SetCarea(*value)
+	}
+	return c
+}
+
+// set field if value's pointer is not nil.
+func (c *ContactCreate) SetNotNilCarea(value *string) *ContactCreate {
+	if value != nil {
+		return c.SetCarea(*value)
+	}
+	return c
+}
+
+// set field if value's pointer is not nil.
+func (c *ContactUpdate) SetNotNilCmobile(value *string) *ContactUpdate {
+	if value != nil {
+		return c.SetCmobile(*value)
+	}
+	return c
+}
+
+// set field if value's pointer is not nil.
+func (c *ContactUpdateOne) SetNotNilCmobile(value *string) *ContactUpdateOne {
+	if value != nil {
+		return c.SetCmobile(*value)
+	}
+	return c
+}
+
+// set field if value's pointer is not nil.
+func (c *ContactCreate) SetNotNilCmobile(value *string) *ContactCreate {
+	if value != nil {
+		return c.SetCmobile(*value)
+	}
+	return c
+}
+
+// set field if value's pointer is not nil.
+func (c *ContactUpdate) SetNotNilCbirthday(value *string) *ContactUpdate {
+	if value != nil {
+		return c.SetCbirthday(*value)
+	}
+	return c
+}
+
+// set field if value's pointer is not nil.
+func (c *ContactUpdateOne) SetNotNilCbirthday(value *string) *ContactUpdateOne {
+	if value != nil {
+		return c.SetCbirthday(*value)
+	}
+	return c
+}
+
+// set field if value's pointer is not nil.
+func (c *ContactCreate) SetNotNilCbirthday(value *string) *ContactCreate {
+	if value != nil {
+		return c.SetCbirthday(*value)
+	}
+	return c
+}
+
+// set field if value's pointer is not nil.
+func (c *ContactUpdate) SetNotNilCbirtharea(value *string) *ContactUpdate {
+	if value != nil {
+		return c.SetCbirtharea(*value)
+	}
+	return c
+}
+
+// set field if value's pointer is not nil.
+func (c *ContactUpdateOne) SetNotNilCbirtharea(value *string) *ContactUpdateOne {
+	if value != nil {
+		return c.SetCbirtharea(*value)
+	}
+	return c
+}
+
+// set field if value's pointer is not nil.
+func (c *ContactCreate) SetNotNilCbirtharea(value *string) *ContactCreate {
+	if value != nil {
+		return c.SetCbirtharea(*value)
+	}
+	return c
+}
+
+// set field if value's pointer is not nil.
+func (c *ContactUpdate) SetNotNilCidcardNo(value *string) *ContactUpdate {
+	if value != nil {
+		return c.SetCidcardNo(*value)
+	}
+	return c
+}
+
+// set field if value's pointer is not nil.
+func (c *ContactUpdateOne) SetNotNilCidcardNo(value *string) *ContactUpdateOne {
+	if value != nil {
+		return c.SetCidcardNo(*value)
+	}
+	return c
+}
+
+// set field if value's pointer is not nil.
+func (c *ContactCreate) SetNotNilCidcardNo(value *string) *ContactCreate {
+	if value != nil {
+		return c.SetCidcardNo(*value)
+	}
+	return c
+}
+
+// set field if value's pointer is not nil.
+func (c *ContactUpdate) SetNotNilCtitle(value *string) *ContactUpdate {
+	if value != nil {
+		return c.SetCtitle(*value)
+	}
+	return c
+}
+
+// set field if value's pointer is not nil.
+func (c *ContactUpdateOne) SetNotNilCtitle(value *string) *ContactUpdateOne {
+	if value != nil {
+		return c.SetCtitle(*value)
+	}
+	return c
+}
+
+// set field if value's pointer is not nil.
+func (c *ContactCreate) SetNotNilCtitle(value *string) *ContactCreate {
+	if value != nil {
+		return c.SetCtitle(*value)
+	}
+	return c
+}
+
+// set field if value's pointer is not nil.
+func (c *ContactUpdate) SetNotNilCc(value *string) *ContactUpdate {
+	if value != nil {
+		return c.SetCc(*value)
+	}
+	return c
+}
+
+// set field if value's pointer is not nil.
+func (c *ContactUpdateOne) SetNotNilCc(value *string) *ContactUpdateOne {
+	if value != nil {
+		return c.SetCc(*value)
+	}
+	return c
+}
+
+// set field if value's pointer is not nil.
+func (c *ContactCreate) SetNotNilCc(value *string) *ContactCreate {
+	if value != nil {
+		return c.SetCc(*value)
+	}
+	return c
+}
+
+// set field if value's pointer is not nil.
+func (c *ContactUpdate) SetNotNilPhone(value *string) *ContactUpdate {
+	if value != nil {
+		return c.SetPhone(*value)
+	}
+	return c
+}
+
+// set field if value's pointer is not nil.
+func (c *ContactUpdateOne) SetNotNilPhone(value *string) *ContactUpdateOne {
+	if value != nil {
+		return c.SetPhone(*value)
+	}
+	return c
+}
+
+// set field if value's pointer is not nil.
+func (c *ContactCreate) SetNotNilPhone(value *string) *ContactCreate {
+	if value != nil {
+		return c.SetPhone(*value)
+	}
+	return c
+}
+
+// set field if value's pointer is not nil.
 func (cb *CreditBalanceUpdate) SetNotNilUpdatedAt(value *time.Time) *CreditBalanceUpdate {
 	if value != nil {
 		return cb.SetUpdatedAt(*value)
@@ -3440,6 +3752,30 @@ func (l *LabelCreate) SetNotNilOrganizationID(value *uint64) *LabelCreate {
 }
 
 // set field if value's pointer is not nil.
+func (l *LabelUpdate) SetNotNilCtype(value *uint64) *LabelUpdate {
+	if value != nil {
+		return l.SetCtype(*value)
+	}
+	return l
+}
+
+// set field if value's pointer is not nil.
+func (l *LabelUpdateOne) SetNotNilCtype(value *uint64) *LabelUpdateOne {
+	if value != nil {
+		return l.SetCtype(*value)
+	}
+	return l
+}
+
+// set field if value's pointer is not nil.
+func (l *LabelCreate) SetNotNilCtype(value *uint64) *LabelCreate {
+	if value != nil {
+		return l.SetCtype(*value)
+	}
+	return l
+}
+
+// set field if value's pointer is not nil.
 func (lr *LabelRelationshipUpdate) SetNotNilUpdatedAt(value *time.Time) *LabelRelationshipUpdate {
 	if value != nil {
 		return lr.SetUpdatedAt(*value)
@@ -3560,6 +3896,30 @@ func (lr *LabelRelationshipCreate) SetNotNilOrganizationID(value *uint64) *Label
 }
 
 // set field if value's pointer is not nil.
+func (lr *LabelRelationshipUpdate) SetNotNilCtype(value *uint64) *LabelRelationshipUpdate {
+	if value != nil {
+		return lr.SetCtype(*value)
+	}
+	return lr
+}
+
+// set field if value's pointer is not nil.
+func (lr *LabelRelationshipUpdateOne) SetNotNilCtype(value *uint64) *LabelRelationshipUpdateOne {
+	if value != nil {
+		return lr.SetCtype(*value)
+	}
+	return lr
+}
+
+// set field if value's pointer is not nil.
+func (lr *LabelRelationshipCreate) SetNotNilCtype(value *uint64) *LabelRelationshipCreate {
+	if value != nil {
+		return lr.SetCtype(*value)
+	}
+	return lr
+}
+
+// set field if value's pointer is not nil.
 func (lt *LabelTaggingUpdate) SetNotNilUpdatedAt(value *time.Time) *LabelTaggingUpdate {
 	if value != nil {
 		return lt.SetUpdatedAt(*value)

+ 65 - 1
hook/aliyun/whatsapp.go

@@ -1,6 +1,7 @@
 package aliyun
 
 import (
+	"encoding/json"
 	"fmt"
 	cams20200606 "github.com/alibabacloud-go/cams-20200606/v2/client"
 	openapi "github.com/alibabacloud-go/darabonba-openapi/v2/client"
@@ -442,13 +443,14 @@ func UpdatePhoneWebhook(phone, custSpaceId, callback string) (*cams20200606.Upda
 }
 
 // ListChatappTemplate 获取模板列表
-func ListChatappTemplate(name, language, auditStatus, templateType, code string, page, size int32) (*cams20200606.ListChatappTemplateResponse, error) {
+func ListChatappTemplate(waId, name, language, auditStatus, templateType, code string, page, size int32) (*cams20200606.ListChatappTemplateResponse, error) {
 	client, _err := CreateCamsClient()
 	if _err != nil {
 		return nil, _err
 	}
 
 	request := &cams20200606.ListChatappTemplateRequest{
+		CustSpaceId: tea.String(waId),
 		Name:        tea.String(name),
 		Language:    tea.String(language),
 		AuditStatus: tea.String(auditStatus),
@@ -511,3 +513,65 @@ func DeleteChatappTemplate(name, language, templateType, templateCode string) (*
 
 	return response, nil
 }
+
+// SendChatappMessage 发送消息
+// @see https://help.aliyun.com/zh/chatapp/developer-reference/api-cams-2020-06-06-sendchatappmessage
+func SendChatappMessage(stype, messageType, templateCode, lang, sfrom, sto, stext string) (*cams20200606.SendChatappMessageResponse, error) {
+	client, _err := CreateCamsClient()
+	if _err != nil {
+		return nil, _err
+	}
+
+	var content = map[string]interface{}{
+		"text": stext,
+	}
+	scontext, _ := json.Marshal(content)
+
+	request := &cams20200606.SendChatappMessageRequest{
+		ChannelType:  tea.String("whatsapp"),
+		Type:         tea.String(stype),
+		MessageType:  tea.String(messageType),
+		TemplateCode: tea.String(templateCode),
+		Language:     tea.String(lang),
+		From:         tea.String(sfrom),
+		To:           tea.String(sto),
+		Content:      tea.String(string(scontext)),
+	}
+
+	response, _err := client.SendChatappMessage(request)
+	if _err != nil {
+		return nil, _err
+	}
+
+	return response, nil
+}
+
+// SendBatchChatappMessage 发送批量消息
+// @see https://help.aliyun.com/zh/chatapp/developer-reference/api-cams-2020-06-06-sendchatappmassmessage
+func SendBatchChatappMessage(stype, messageType, templateCode, lang, sfrom, stext string, sto []string) (*cams20200606.SendChatappMassMessageResponse, error) {
+	client, _err := CreateCamsClient()
+	if _err != nil {
+		return nil, _err
+	}
+
+	senderList := make([]*cams20200606.SendChatappMassMessageRequestSenderList, 0)
+	for _, v := range sto {
+		senderList = append(senderList, &cams20200606.SendChatappMassMessageRequestSenderList{
+			To: &v,
+		})
+	}
+	request := &cams20200606.SendChatappMassMessageRequest{
+		ChannelType:  tea.String("whatsapp"),
+		TemplateCode: tea.String(templateCode),
+		Language:     tea.String(lang),
+		From:         tea.String(sfrom),
+		SenderList:   senderList,
+	}
+
+	response, _err := client.SendChatappMassMessage(request)
+	if _err != nil {
+		return nil, _err
+	}
+
+	return response, nil
+}

+ 44 - 0
internal/handler/contact/create_whatsapp_contact_handler.go

@@ -0,0 +1,44 @@
+package contact
+
+import (
+	"net/http"
+
+	"github.com/zeromicro/go-zero/rest/httpx"
+
+	"wechat-api/internal/logic/contact"
+	"wechat-api/internal/svc"
+	"wechat-api/internal/types"
+)
+
+// swagger:route post /contact/createWhatsappContact contact CreateWhatsappContact
+//
+// Whatsapp联系人创建
+//
+// Whatsapp联系人创建
+//
+// Parameters:
+//  + name: body
+//    require: true
+//    in: body
+//    type: CreateWhatsappContactReq
+//
+// Responses:
+//  200: BaseMsgResp
+
+func CreateWhatsappContactHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
+	return func(w http.ResponseWriter, r *http.Request) {
+		var req types.CreateWhatsappContactReq
+		if err := httpx.Parse(r, &req, true); err != nil {
+			httpx.ErrorCtx(r.Context(), w, err)
+			return
+		}
+
+		l := contact.NewCreateWhatsappContactLogic(r.Context(), svcCtx)
+		resp, err := l.CreateWhatsappContact(&req)
+		if err != nil {
+			httpx.ErrorCtx(r.Context(), w, err)
+		} else {
+			httpx.OkJsonCtx(r.Context(), w, resp)
+		}
+	}
+}

+ 44 - 0
internal/handler/contact/delete_whatsapp_contact_handler.go

@@ -0,0 +1,44 @@
+package contact
+
+import (
+	"net/http"
+
+	"github.com/zeromicro/go-zero/rest/httpx"
+
+	"wechat-api/internal/logic/contact"
+	"wechat-api/internal/svc"
+	"wechat-api/internal/types"
+)
+
+// swagger:route post /contact/deleteWhatsappContact contact DeleteWhatsappContact
+//
+// Whatsapp联系人删除
+//
+// Whatsapp联系人删除
+//
+// Parameters:
+//  + name: body
+//    require: true
+//    in: body
+//    type: IDsReq
+//
+// Responses:
+//  200: BaseMsgResp
+
+func DeleteWhatsappContactHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
+	return func(w http.ResponseWriter, r *http.Request) {
+		var req types.IDsReq
+		if err := httpx.Parse(r, &req, true); err != nil {
+			httpx.ErrorCtx(r.Context(), w, err)
+			return
+		}
+
+		l := contact.NewDeleteWhatsappContactLogic(r.Context(), svcCtx)
+		resp, err := l.DeleteWhatsappContact(&req)
+		if err != nil {
+			httpx.ErrorCtx(r.Context(), w, err)
+		} else {
+			httpx.OkJsonCtx(r.Context(), w, resp)
+		}
+	}
+}

+ 44 - 0
internal/handler/contact/get_whatsapp_contact_handler.go

@@ -0,0 +1,44 @@
+package contact
+
+import (
+	"net/http"
+
+	"github.com/zeromicro/go-zero/rest/httpx"
+
+	"wechat-api/internal/logic/contact"
+	"wechat-api/internal/svc"
+	"wechat-api/internal/types"
+)
+
+// swagger:route post /contact/getWhatsappContact contact GetWhatsappContact
+//
+// Whatsapp联系人详情
+//
+// Whatsapp联系人详情
+//
+// Parameters:
+//  + name: body
+//    require: true
+//    in: body
+//    type: IDReq
+//
+// Responses:
+//  200: BaseMsgResp
+
+func GetWhatsappContactHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
+	return func(w http.ResponseWriter, r *http.Request) {
+		var req types.IDReq
+		if err := httpx.Parse(r, &req, true); err != nil {
+			httpx.ErrorCtx(r.Context(), w, err)
+			return
+		}
+
+		l := contact.NewGetWhatsappContactLogic(r.Context(), svcCtx)
+		resp, err := l.GetWhatsappContact(&req)
+		if err != nil {
+			httpx.ErrorCtx(r.Context(), w, err)
+		} else {
+			httpx.OkJsonCtx(r.Context(), w, resp)
+		}
+	}
+}

+ 44 - 0
internal/handler/contact/get_whatsapp_contact_list_handler.go

@@ -0,0 +1,44 @@
+package contact
+
+import (
+	"net/http"
+
+	"github.com/zeromicro/go-zero/rest/httpx"
+
+	"wechat-api/internal/logic/contact"
+	"wechat-api/internal/svc"
+	"wechat-api/internal/types"
+)
+
+// swagger:route post /contact/getWhatsappContactList contact GetWhatsappContactList
+//
+// Whatsapp联系人列表
+//
+// Whatsapp联系人列表
+//
+// Parameters:
+//  + name: body
+//    require: true
+//    in: body
+//    type: WhatsappContactListReq
+//
+// Responses:
+//  200: ContactListResp
+
+func GetWhatsappContactListHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
+	return func(w http.ResponseWriter, r *http.Request) {
+		var req types.WhatsappContactListReq
+		if err := httpx.Parse(r, &req, true); err != nil {
+			httpx.ErrorCtx(r.Context(), w, err)
+			return
+		}
+
+		l := contact.NewGetWhatsappContactListLogic(r.Context(), svcCtx)
+		resp, err := l.GetWhatsappContactList(&req)
+		if err != nil {
+			httpx.ErrorCtx(r.Context(), w, err)
+		} else {
+			httpx.OkJsonCtx(r.Context(), w, resp)
+		}
+	}
+}

+ 70 - 0
internal/handler/contact/import_whatsapp_contact_handler.go

@@ -0,0 +1,70 @@
+package contact
+
+import (
+	"errors"
+	"fmt"
+	"github.com/zeromicro/go-zero/rest/httpx"
+	"net/http"
+
+	"wechat-api/internal/logic/contact"
+	"wechat-api/internal/svc"
+	"wechat-api/internal/types"
+)
+
+const (
+	defaultMultipartMemory = 32 << 20 // 32 MB
+)
+
+// swagger:route post /contact/importWhatsappContact contact ImportWhatsappContact
+//
+// 导入Whatsapp联系人
+//
+// 导入Whatsapp联系人
+//
+// Parameters:
+//  + name: body
+//    require: true
+//    in: body
+//    type: ImportWhatsappContactReq
+//
+// Responses:
+//  200: BaseDataInfo
+
+func ImportWhatsappContactHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
+	return func(w http.ResponseWriter, r *http.Request) {
+		if err := r.ParseMultipartForm(defaultMultipartMemory); err != nil {
+			httpx.Error(w, err)
+			return
+		}
+
+		file, header, err := r.FormFile("file")
+
+		if err != nil {
+			httpx.ErrorCtx(r.Context(), w, err)
+			return
+		}
+		if file == nil {
+			httpx.ErrorCtx(r.Context(), w, errors.New("upload file cannot be null"))
+			return
+		}
+
+		fmt.Printf("header=%+v size=%d filename=%v\n", header.Header, header.Size, header.Filename)
+
+		var req types.ImportWhatsappContactReq
+		if err := httpx.Parse(r, &req, true); err != nil {
+			httpx.ErrorCtx(r.Context(), w, err)
+			return
+		}
+
+		l := contact.NewImportWhatsappContactLogic(r.Context(), svcCtx)
+		resp, err := l.ImportWhatsappContact(&req, file)
+
+		// 删除临时文件
+		_ = r.MultipartForm.RemoveAll()
+		if err != nil {
+			httpx.ErrorCtx(r.Context(), w, err)
+		} else {
+			httpx.OkJsonCtx(r.Context(), w, resp)
+		}
+	}
+}

+ 44 - 0
internal/handler/contact/update_whatsapp_contact_handler.go

@@ -0,0 +1,44 @@
+package contact
+
+import (
+	"net/http"
+
+	"github.com/zeromicro/go-zero/rest/httpx"
+
+	"wechat-api/internal/logic/contact"
+	"wechat-api/internal/svc"
+	"wechat-api/internal/types"
+)
+
+// swagger:route post /contact/updateWhatsappContact contact UpdateWhatsappContact
+//
+// Whatsapp联系人编辑
+//
+// Whatsapp联系人编辑
+//
+// Parameters:
+//  + name: body
+//    require: true
+//    in: body
+//    type: CreateWhatsappContactReq
+//
+// Responses:
+//  200: BaseMsgResp
+
+func UpdateWhatsappContactHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
+	return func(w http.ResponseWriter, r *http.Request) {
+		var req types.CreateWhatsappContactReq
+		if err := httpx.Parse(r, &req, true); err != nil {
+			httpx.ErrorCtx(r.Context(), w, err)
+			return
+		}
+
+		l := contact.NewUpdateWhatsappContactLogic(r.Context(), svcCtx)
+		resp, err := l.UpdateWhatsappContact(&req)
+		if err != nil {
+			httpx.ErrorCtx(r.Context(), w, err)
+		} else {
+			httpx.OkJsonCtx(r.Context(), w, resp)
+		}
+	}
+}

+ 44 - 0
internal/handler/label_relationship/set_whatsapp_contact_batch_label_handler.go

@@ -0,0 +1,44 @@
+package label_relationship
+
+import (
+	"net/http"
+
+	"github.com/zeromicro/go-zero/rest/httpx"
+
+	"wechat-api/internal/logic/label_relationship"
+	"wechat-api/internal/svc"
+	"wechat-api/internal/types"
+)
+
+// swagger:route post /label_relationship/setWhatsappContactBatchLabel label_relationship SetWhatsappContactBatchLabel
+//
+// 批量更新WhatsappContact的Label信息
+//
+// 批量更新WhatsappContact的Label信息
+//
+// Parameters:
+//  + name: body
+//    require: true
+//    in: body
+//    type: BatchLabelRelationshipsInfo
+//
+// Responses:
+//  200: BaseMsgResp
+
+func SetWhatsappContactBatchLabelHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
+	return func(w http.ResponseWriter, r *http.Request) {
+		var req types.BatchLabelRelationshipsInfo
+		if err := httpx.Parse(r, &req, true); err != nil {
+			httpx.ErrorCtx(r.Context(), w, err)
+			return
+		}
+
+		l := label_relationship.NewSetWhatsappContactBatchLabelLogic(r.Context(), svcCtx)
+		resp, err := l.SetWhatsappContactBatchLabel(&req)
+		if err != nil {
+			httpx.ErrorCtx(r.Context(), w, err)
+		} else {
+			httpx.OkJsonCtx(r.Context(), w, resp)
+		}
+	}
+}

+ 44 - 0
internal/handler/label_relationship/set_whatsapp_contact_label_handler.go

@@ -0,0 +1,44 @@
+package label_relationship
+
+import (
+	"net/http"
+
+	"github.com/zeromicro/go-zero/rest/httpx"
+
+	"wechat-api/internal/logic/label_relationship"
+	"wechat-api/internal/svc"
+	"wechat-api/internal/types"
+)
+
+// swagger:route post /label_relationship/setWhatsappContactLabel label_relationship SetWhatsappContactLabel
+//
+// 更新WhatsappContact的Label信息
+//
+// 更新WhatsappContact的Label信息
+//
+// Parameters:
+//  + name: body
+//    require: true
+//    in: body
+//    type: LabelRelationshipInfo
+//
+// Responses:
+//  200: BaseMsgResp
+
+func SetWhatsappContactLabelHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
+	return func(w http.ResponseWriter, r *http.Request) {
+		var req types.LabelRelationshipsInfo
+		if err := httpx.Parse(r, &req, true); err != nil {
+			httpx.ErrorCtx(r.Context(), w, err)
+			return
+		}
+
+		l := label_relationship.NewSetWhatsappContactLabelLogic(r.Context(), svcCtx)
+		resp, err := l.SetWhatsappContactLabel(&req)
+		if err != nil {
+			httpx.ErrorCtx(r.Context(), w, err)
+		} else {
+			httpx.OkJsonCtx(r.Context(), w, resp)
+		}
+	}
+}

+ 40 - 0
internal/handler/routes.go

@@ -270,6 +270,16 @@ func RegisterHandlers(server *rest.Server, serverCtx *svc.ServiceContext) {
 					Path:    "/label_relationship",
 					Handler: label_relationship.GetLabelRelationshipByIdHandler(serverCtx),
 				},
+				{
+					Method:  http.MethodPost,
+					Path:    "/label_relationship/setWhatsappContactLabel",
+					Handler: label_relationship.SetWhatsappContactLabelHandler(serverCtx),
+				},
+				{
+					Method:  http.MethodPost,
+					Path:    "/label_relationship/setWhatsappContactBatchLabel",
+					Handler: label_relationship.SetWhatsappContactBatchLabelHandler(serverCtx),
+				},
 			}...,
 		),
 		rest.WithJwt(serverCtx.Config.Auth.AccessSecret),
@@ -363,6 +373,36 @@ func RegisterHandlers(server *rest.Server, serverCtx *svc.ServiceContext) {
 					Path:    "/contact/changeBlockList",
 					Handler: contact.ChangeBlockListHandler(serverCtx),
 				},
+				{
+					Method:  http.MethodPost,
+					Path:    "/contact/importWhatsappContact",
+					Handler: contact.ImportWhatsappContactHandler(serverCtx),
+				},
+				{
+					Method:  http.MethodPost,
+					Path:    "/contact/getWhatsappContactList",
+					Handler: contact.GetWhatsappContactListHandler(serverCtx),
+				},
+				{
+					Method:  http.MethodPost,
+					Path:    "/contact/createWhatsappContact",
+					Handler: contact.CreateWhatsappContactHandler(serverCtx),
+				},
+				{
+					Method:  http.MethodPost,
+					Path:    "/contact/updateWhatsappContact",
+					Handler: contact.UpdateWhatsappContactHandler(serverCtx),
+				},
+				{
+					Method:  http.MethodPost,
+					Path:    "/contact/deleteWhatsappContact",
+					Handler: contact.DeleteWhatsappContactHandler(serverCtx),
+				},
+				{
+					Method:  http.MethodPost,
+					Path:    "/contact/getWhatsappContact",
+					Handler: contact.GetWhatsappContactHandler(serverCtx),
+				},
 			}...,
 		),
 		rest.WithJwt(serverCtx.Config.Auth.AccessSecret),

+ 1 - 0
internal/logic/batch_msg/create_batch_msg_logic.go

@@ -191,6 +191,7 @@ func (l *CreateBatchMsgLogic) CreateBatchMsg(req *types.BatchMsgInfo) (*types.Ba
 		SetNillableSendTime(sendTime).
 		SetNotNilType(req.Type).
 		SetNotNilOrganizationID(&organizationId).
+		SetCtype(1).
 		Save(l.ctx)
 
 	if err != nil {

+ 1 - 0
internal/logic/batch_msg/get_batch_msg_list_logic.go

@@ -35,6 +35,7 @@ func (l *GetBatchMsgListLogic) GetBatchMsgList(req *types.BatchMsgListReq) (*typ
 	var predicates []predicate.BatchMsg
 	predicates = append(predicates, batchmsg.Type(*req.Type))
 	predicates = append(predicates, batchmsg.OrganizationIDEQ(organizationId))
+	predicates = append(predicates, batchmsg.Ctype(1))
 	if req.BatchNo != nil {
 		predicates = append(predicates, batchmsg.BatchNoContains(*req.BatchNo))
 	}

+ 56 - 0
internal/logic/contact/create_whatsapp_contact_logic.go

@@ -0,0 +1,56 @@
+package contact
+
+import (
+	"context"
+	"github.com/suyuan32/simple-admin-common/utils/uuidx"
+	"wechat-api/internal/utils/dberrorhandler"
+
+	"wechat-api/internal/svc"
+	"wechat-api/internal/types"
+
+	"github.com/zeromicro/go-zero/core/logx"
+)
+
+type CreateWhatsappContactLogic struct {
+	logx.Logger
+	ctx    context.Context
+	svcCtx *svc.ServiceContext
+}
+
+func NewCreateWhatsappContactLogic(ctx context.Context, svcCtx *svc.ServiceContext) *CreateWhatsappContactLogic {
+	return &CreateWhatsappContactLogic{
+		Logger: logx.WithContext(ctx),
+		ctx:    ctx,
+		svcCtx: svcCtx}
+}
+
+func (l *CreateWhatsappContactLogic) CreateWhatsappContact(req *types.CreateWhatsappContactReq) (*types.BaseMsgResp, error) {
+	resp := types.BaseMsgResp{}
+	organizationId := l.ctx.Value("organizationId").(uint64)
+
+	uuidstr := uuidx.NewUUID().String()
+	_, err := l.svcCtx.DB.Contact.Create().SetCtype(2).
+		SetNotNilCc(req.Cc).
+		SetNotNilPhone(req.Phone).
+		SetWxWxid(uuidstr).
+		SetWxid(uuidstr).
+		SetType(5).
+		SetNotNilMarkname(req.Markname).
+		SetOrganizationID(organizationId).
+		SetNotNilCarea(req.Carea).
+		SetNotNilCage(req.Cage).
+		SetNotNilCsex(req.Csex).
+		SetNotNilCbirtharea(req.Cbirtharea).
+		SetNotNilCbirthday(req.Cbirtyday).
+		SetNotNilCtitle(req.Ctitle).
+		SetNotNilCidcardNo(req.CidcardNo).
+		SetNotNilCname(req.Cname).
+		Save(l.ctx)
+
+	if err != nil {
+		return nil, dberrorhandler.DefaultEntError(l.Logger, err, req)
+	}
+	resp.Msg = "创建成功"
+
+	return &resp, nil
+}

+ 41 - 0
internal/logic/contact/delete_whatsapp_contact_logic.go

@@ -0,0 +1,41 @@
+package contact
+
+import (
+	"context"
+	"github.com/suyuan32/simple-admin-common/msg/errormsg"
+	"wechat-api/ent/contact"
+	"wechat-api/internal/utils/dberrorhandler"
+
+	"wechat-api/internal/svc"
+	"wechat-api/internal/types"
+
+	"github.com/zeromicro/go-zero/core/logx"
+)
+
+type DeleteWhatsappContactLogic struct {
+	logx.Logger
+	ctx    context.Context
+	svcCtx *svc.ServiceContext
+}
+
+func NewDeleteWhatsappContactLogic(ctx context.Context, svcCtx *svc.ServiceContext) *DeleteWhatsappContactLogic {
+	return &DeleteWhatsappContactLogic{
+		Logger: logx.WithContext(ctx),
+		ctx:    ctx,
+		svcCtx: svcCtx}
+}
+
+func (l *DeleteWhatsappContactLogic) DeleteWhatsappContact(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),
+		contact.Ctype(2),
+	).Exec(l.ctx)
+
+	if err != nil {
+		return nil, dberrorhandler.DefaultEntError(l.Logger, err, req)
+	}
+
+	return &types.BaseMsgResp{Msg: errormsg.DeleteSuccess}, nil
+}

+ 104 - 0
internal/logic/contact/get_whatsapp_contact_list_logic.go

@@ -0,0 +1,104 @@
+package contact
+
+import (
+	"context"
+	"github.com/suyuan32/simple-admin-common/msg/errormsg"
+	"github.com/suyuan32/simple-admin-common/utils/pointy"
+	"wechat-api/ent"
+	"wechat-api/ent/contact"
+	"wechat-api/ent/label"
+	"wechat-api/ent/labelrelationship"
+	"wechat-api/ent/predicate"
+	"wechat-api/internal/utils/dberrorhandler"
+
+	"wechat-api/internal/svc"
+	"wechat-api/internal/types"
+
+	"github.com/zeromicro/go-zero/core/logx"
+)
+
+type GetWhatsappContactListLogic struct {
+	logx.Logger
+	ctx    context.Context
+	svcCtx *svc.ServiceContext
+}
+
+func NewGetWhatsappContactListLogic(ctx context.Context, svcCtx *svc.ServiceContext) *GetWhatsappContactListLogic {
+	return &GetWhatsappContactListLogic{
+		Logger: logx.WithContext(ctx),
+		ctx:    ctx,
+		svcCtx: svcCtx}
+}
+
+func (l *GetWhatsappContactListLogic) GetWhatsappContactList(req *types.WhatsappContactListReq) (*types.ContactListResp, error) {
+	organizationId := l.ctx.Value("organizationId").(uint64)
+	var predicates []predicate.Contact
+	predicates = append(predicates, contact.OrganizationIDEQ(organizationId))
+	predicates = append(predicates, contact.Ctype(2))
+	if len(req.LabelIDs) > 0 {
+		predicates = append(predicates, contact.HasContactRelationshipsWith(
+			labelrelationship.HasLabelsWith(
+				label.IDIn(req.LabelIDs...),
+			),
+		))
+	}
+	if req.Phone != nil {
+		predicates = append(predicates, contact.WxWxidContains(*req.Phone))
+	}
+	if req.Name != nil {
+		predicates = append(predicates, contact.NicknameContains(*req.Name))
+	}
+
+	data, err := l.svcCtx.DB.Contact.Query().Where(predicates...).WithContactRelationships(func(query *ent.LabelRelationshipQuery) {
+		query.WithLabels()
+	}).Page(l.ctx, req.Page, req.PageSize)
+
+	if err != nil {
+		return nil, dberrorhandler.DefaultEntError(l.Logger, err, req)
+	}
+
+	resp := &types.ContactListResp{}
+	resp.Msg = errormsg.Success
+	resp.Data.Total = data.PageDetails.Total
+
+	for _, v := range data.List {
+		labelRelationships := make([]types.ContactLabelList, 0)
+		if v.Edges.ContactRelationships != nil {
+			for _, lr := range v.Edges.ContactRelationships {
+				if lr.Edges.Labels == nil {
+					continue
+				}
+				labelRelationships = append(labelRelationships, types.ContactLabelList{
+					Label: &lr.Edges.Labels.Name,
+					Value: &lr.LabelID,
+				})
+			}
+		}
+
+		resp.Data.Data = append(resp.Data.Data,
+			types.ContactInfo{
+				BaseIDInfo: types.BaseIDInfo{
+					Id:        &v.ID,
+					CreatedAt: pointy.GetPointer(v.CreatedAt.UnixMilli()),
+					UpdatedAt: pointy.GetPointer(v.UpdatedAt.UnixMilli()),
+				},
+				Status:             &v.Status,
+				Nickname:           &v.Nickname,
+				Markname:           &v.Markname,
+				LabelRelationships: labelRelationships,
+				OrganizationId:     &v.OrganizationID,
+				Ctype:              &v.Ctype,
+				Cname:              &v.Cname,
+				Csex:               &v.Csex,
+				Cage:               &v.Cage,
+				Carea:              &v.Carea,
+				Cmobile:            &v.Cmobile,
+				Cbirtyday:          &v.Cbirthday,
+				Cbirtharea:         &v.Cbirtharea,
+				CidcardNo:          &v.CidcardNo,
+				Ctitle:             &v.Ctitle,
+			})
+	}
+
+	return resp, nil
+}

+ 66 - 0
internal/logic/contact/get_whatsapp_contact_logic.go

@@ -0,0 +1,66 @@
+package contact
+
+import (
+	"context"
+	"github.com/suyuan32/simple-admin-common/msg/errormsg"
+	"github.com/suyuan32/simple-admin-common/utils/pointy"
+	"wechat-api/ent/contact"
+	"wechat-api/internal/utils/dberrorhandler"
+
+	"wechat-api/internal/svc"
+	"wechat-api/internal/types"
+
+	"github.com/zeromicro/go-zero/core/logx"
+)
+
+type GetWhatsappContactLogic struct {
+	logx.Logger
+	ctx    context.Context
+	svcCtx *svc.ServiceContext
+}
+
+func NewGetWhatsappContactLogic(ctx context.Context, svcCtx *svc.ServiceContext) *GetWhatsappContactLogic {
+	return &GetWhatsappContactLogic{
+		Logger: logx.WithContext(ctx),
+		ctx:    ctx,
+		svcCtx: svcCtx}
+}
+
+func (l *GetWhatsappContactLogic) GetWhatsappContact(req *types.IDReq) (resp *types.ContactInfoResp, err error) {
+	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
+		).
+		Only(l.ctx)
+	if err != nil {
+		return nil, dberrorhandler.DefaultEntError(l.Logger, err, req)
+	}
+
+	return &types.ContactInfoResp{
+		BaseDataInfo: types.BaseDataInfo{
+			Code: 0,
+			Msg:  errormsg.Success,
+		},
+		Data: types.ContactInfo{
+			BaseIDInfo: types.BaseIDInfo{
+				Id:        &data.ID,
+				CreatedAt: pointy.GetPointer(data.CreatedAt.UnixMilli()),
+				UpdatedAt: pointy.GetPointer(data.UpdatedAt.UnixMilli()),
+			},
+			Markname:       &data.Markname,
+			OrganizationId: &data.OrganizationID,
+			Ctype:          &data.Ctype,
+			Cname:          &data.Cname,
+			Csex:           &data.Csex,
+			Cage:           &data.Cage,
+			Carea:          &data.Carea,
+			Cmobile:        &data.Cmobile,
+			Cbirtyday:      &data.Cbirthday,
+			Cbirtharea:     &data.Cbirtharea,
+			CidcardNo:      &data.CidcardNo,
+			Ctitle:         &data.Ctitle,
+		},
+	}, nil
+}

+ 111 - 0
internal/logic/contact/import_whatsapp_contact_logic.go

@@ -0,0 +1,111 @@
+package contact
+
+import (
+	"context"
+	"encoding/csv"
+	"fmt"
+	"github.com/suyuan32/simple-admin-common/msg/errormsg"
+	"github.com/suyuan32/simple-admin-common/utils/uuidx"
+	"mime/multipart"
+	"strconv"
+	"strings"
+	"wechat-api/internal/svc"
+	"wechat-api/internal/types"
+
+	"github.com/zeromicro/go-zero/core/logx"
+)
+
+type ImportWhatsappContactLogic struct {
+	logx.Logger
+	ctx    context.Context
+	svcCtx *svc.ServiceContext
+}
+
+func NewImportWhatsappContactLogic(ctx context.Context, svcCtx *svc.ServiceContext) *ImportWhatsappContactLogic {
+	return &ImportWhatsappContactLogic{
+		Logger: logx.WithContext(ctx),
+		ctx:    ctx,
+		svcCtx: svcCtx}
+}
+
+func (l *ImportWhatsappContactLogic) ImportWhatsappContact(req *types.ImportWhatsappContactReq, file multipart.File) (*types.BaseDataInfo, error) {
+	organizationId := l.ctx.Value("organizationId").(uint64)
+
+	resp := types.BaseDataInfo{}
+
+	reader := csv.NewReader(file)
+	records, err := reader.ReadAll()
+	if err != nil {
+		return nil, err
+	}
+
+	var total, success, fail, add_labels int
+	var conditions = "{}"
+	for idx, record := range records {
+		if idx == 0 {
+			continue
+		}
+		total++
+
+		uuidstr := uuidx.NewUUID().String()
+		csex, _ := strconv.Atoi(trim(record[5]))
+		cage, _ := strconv.Atoi(trim(record[7]))
+		newContact, err := l.svcCtx.DB.Contact.Create().SetCtype(2).
+			SetCc(record[0]).
+			SetPhone(record[1]).
+			SetType(5).
+			SetWxWxid(uuidstr).
+			SetWxid(uuidstr).
+			SetCname(trim(record[2])).
+			SetMarkname(trim(record[3])).
+			SetCsex(csex).
+			SetCage(cage).
+			SetCtitle(trim(record[6])).
+			SetCarea(trim(record[9])).
+			SetCbirthday(trim(record[8])).
+			SetCbirtharea(trim(record[10])).
+			SetCidcardNo(trim(record[11])).
+			SetOrganizationID(organizationId).
+			Save(l.ctx)
+		if err != nil {
+			l.Logger.Error("insert to whatsapp contact failed. err=%v\n", err)
+			fail++
+		} else {
+			success++
+		}
+
+		labels := trim(record[4])
+		if labels != "" {
+			for _, value := range strings.Split(labels, "+") {
+				newLabel, err := l.svcCtx.DB.Label.Create().SetCtype(2).
+					SetName(value).
+					SetType(5).
+					SetNotNilConditions(&conditions).
+					SetOrganizationID(organizationId).
+					Save(l.ctx)
+				if err != nil {
+					l.Logger.Errorf("insert into whatsapp label failed.err=%v\n", err)
+				}
+				_, err = l.svcCtx.DB.LabelRelationship.Create().
+					SetLabelID(newLabel.ID).
+					SetContactID(newContact.ID).
+					SetOrganizationID(organizationId).
+					Save(l.ctx)
+				if err != nil {
+					l.Logger.Errorf("insert into whatsapp label-relationship failed.err=%v\n", err)
+				} else {
+					add_labels++
+				}
+			}
+		}
+	}
+
+	resp.Code = 0
+	resp.Msg = errormsg.Success
+	resp.Data = fmt.Sprintf("upload finished. tota:%d success:%d failed:%d add_labels:%d\n", total, success, fail, add_labels)
+	return &resp, nil
+}
+
+func trim(s string) string {
+	return strings.Trim(s, " \r\n\t")
+}

+ 52 - 0
internal/logic/contact/update_whatsapp_contact_logic.go

@@ -0,0 +1,52 @@
+package contact
+
+import (
+	"context"
+	"wechat-api/internal/utils/dberrorhandler"
+
+	"wechat-api/internal/svc"
+	"wechat-api/internal/types"
+
+	"github.com/zeromicro/go-zero/core/logx"
+)
+
+type UpdateWhatsappContactLogic struct {
+	logx.Logger
+	ctx    context.Context
+	svcCtx *svc.ServiceContext
+}
+
+func NewUpdateWhatsappContactLogic(ctx context.Context, svcCtx *svc.ServiceContext) *UpdateWhatsappContactLogic {
+	return &UpdateWhatsappContactLogic{
+		Logger: logx.WithContext(ctx),
+		ctx:    ctx,
+		svcCtx: svcCtx}
+}
+
+func (l *UpdateWhatsappContactLogic) UpdateWhatsappContact(req *types.CreateWhatsappContactReq) (*types.BaseMsgResp, error) {
+	resp := types.BaseMsgResp{}
+	organizationId := l.ctx.Value("organizationId").(uint64)
+
+	_, err := l.svcCtx.DB.Contact.UpdateOneID(*req.Id).
+		SetNotNilCc(req.Cc).
+		SetNotNilPhone(req.Phone).
+		SetType(5).
+		SetNotNilMarkname(req.Markname).
+		SetOrganizationID(organizationId).
+		SetNotNilCarea(req.Carea).
+		SetNotNilCage(req.Cage).
+		SetNotNilCsex(req.Csex).
+		SetNotNilCbirtharea(req.Cbirtharea).
+		SetNotNilCbirthday(req.Cbirtyday).
+		SetNotNilCtitle(req.Ctitle).
+		SetNotNilCidcardNo(req.CidcardNo).
+		SetNotNilCname(req.Cname).
+		Save(l.ctx)
+
+	if err != nil {
+		return nil, dberrorhandler.DefaultEntError(l.Logger, err, req)
+	}
+	resp.Msg = "更新成功"
+
+	return &resp, nil
+}

+ 1 - 0
internal/logic/label/create_label_logic.go

@@ -42,6 +42,7 @@ func (l *CreateLabelLogic) CreateLabel(req *types.LabelInfo) (*types.BaseMsgResp
 		SetNotNilMode(req.Mode).
 		SetNotNilConditions(&conditions).
 		SetOrganizationID(organizationId).
+		SetCtype(1).
 		Save(l.ctx)
 
 	if err != nil {

+ 1 - 0
internal/logic/label/get_label_batch_select_list_logic.go

@@ -30,6 +30,7 @@ func (l *GetLabelBatchSelectListLogic) GetLabelBatchSelectList(req *types.LabelL
 	organizationId := l.ctx.Value("organizationId").(uint64)
 	var predicates []predicate.Label
 	predicates = append(predicates, label.OrganizationIDEQ(organizationId))
+	predicates = append(predicates, label.Ctype(1))
 	if req.Name != nil {
 		predicates = append(predicates, label.NameContains(*req.Name))
 	}

+ 1 - 0
internal/logic/label/get_label_contacts_logic.go

@@ -36,6 +36,7 @@ func (l *GetLabelContactsLogic) GetLabelContacts(req *types.LabelListReq) (*type
 	}
 	var predicates []predicate.Label
 	predicates = append(predicates, label.OrganizationIDEQ(organizationId))
+	predicates = append(predicates, label.Ctype(1))
 	if len(req.LabelIDs) > 0 {
 		predicates = append(predicates, label.IDIn(req.LabelIDs...))
 	}

+ 1 - 0
internal/logic/label/get_label_list_logic.go

@@ -63,6 +63,7 @@ func (l *GetLabelListLogic) GetLabelList(req *types.LabelListReq) (*types.LabelL
 	fmt.Printf("---------------isAdmin----------------: %+v\n\n", isAdmin)
 	var predicates []predicate.Label
 	predicates = append(predicates, label.OrganizationIDEQ(organizationId))
+	predicates = append(predicates, label.Ctype(1))
 	if req.Type != nil {
 		predicates = append(predicates, label.TypeEQ(*req.Type))
 	}

+ 1 - 0
internal/logic/label/get_label_select_list_logic.go

@@ -30,6 +30,7 @@ func (l *GetLabelSelectListLogic) GetLabelSelectList(req *types.LabelListReq) (*
 	organizationId := l.ctx.Value("organizationId").(uint64)
 	var predicates []predicate.Label
 	predicates = append(predicates, label.OrganizationIDEQ(organizationId))
+	predicates = append(predicates, label.Ctype(1))
 	if req.Type != nil {
 		predicates = append(predicates, label.TypeEQ(*req.Type))
 	}

+ 97 - 0
internal/logic/label_relationship/set_whatsapp_contact_batch_label_logic.go

@@ -0,0 +1,97 @@
+package label_relationship
+
+import (
+	"context"
+	"github.com/suyuan32/simple-admin-common/msg/errormsg"
+	"wechat-api/ent/contact"
+	"wechat-api/ent/labelrelationship"
+	"wechat-api/internal/utils/dberrorhandler"
+
+	"wechat-api/internal/svc"
+	"wechat-api/internal/types"
+
+	"github.com/zeromicro/go-zero/core/logx"
+)
+
+type SetWhatsappContactBatchLabelLogic struct {
+	logx.Logger
+	ctx    context.Context
+	svcCtx *svc.ServiceContext
+}
+
+func NewSetWhatsappContactBatchLabelLogic(ctx context.Context, svcCtx *svc.ServiceContext) *SetWhatsappContactBatchLabelLogic {
+	return &SetWhatsappContactBatchLabelLogic{
+		Logger: logx.WithContext(ctx),
+		ctx:    ctx,
+		svcCtx: svcCtx}
+}
+
+func (l *SetWhatsappContactBatchLabelLogic) SetWhatsappContactBatchLabel(req *types.BatchLabelRelationshipsInfo) (*types.BaseMsgResp, error) {
+	organizationId := l.ctx.Value("organizationId").(uint64)
+
+	// 遍历所有联系人
+	for _, contactId := range req.ContactIds {
+		// 开始事务
+		tx, err := l.svcCtx.DB.Tx(context.Background())
+		if err != nil {
+			return nil, dberrorhandler.DefaultEntError(l.Logger, err, req)
+		}
+		// 获取联系人信息
+		_, err = tx.Contact.Query().Where(
+			contact.ID(contactId),
+			contact.OrganizationIDEQ(organizationId),
+			contact.Ctype(2),
+		).Only(l.ctx)
+
+		// 获取联系人当前已关联的标签
+		currentLabelRelationships, err := tx.LabelRelationship.Query().Where(labelrelationship.ContactID(contactId)).All(l.ctx)
+		if err != nil {
+			_ = tx.Rollback()
+			return nil, dberrorhandler.DefaultEntError(l.Logger, err, req)
+		}
+
+		// 提取当前标签ID
+		var currentLabelIds []uint64
+		for _, relationship := range currentLabelRelationships {
+			currentLabelIds = append(currentLabelIds, relationship.LabelID)
+		}
+
+		// 对比新旧标签ID,找出需要新增和移除的标签
+		changeLabelIds, _ := compareLabelIdsForIncrement(req.LabelIds, currentLabelIds, req.UpdateType)
+		// 如果 req.UpdateType 为空,或 req.UpdateType 的值为 “all” 时
+		if req.UpdateType == -1 {
+			// 删除需要移除的标签关系
+			for _, id := range changeLabelIds {
+				_, err := tx.LabelRelationship.
+					Delete().
+					Where(
+						labelrelationship.ContactID(contactId),
+						labelrelationship.LabelID(id),
+					).
+					Exec(l.ctx)
+				if err != nil {
+					_ = tx.Rollback()
+					return nil, dberrorhandler.DefaultEntError(l.Logger, err, req)
+				}
+			}
+		} else {
+			// 创建需要新增的标签关系
+			for _, id := range changeLabelIds {
+				_, _ = tx.LabelRelationship.Create().
+					SetLabelID(id).
+					SetContactID(contactId).
+					SetOrganizationID(organizationId).
+					Save(l.ctx)
+				//if err != nil {
+				//	return nil, dberrorhandler.DefaultEntError(l.Logger, err, req)
+				//}
+			}
+		}
+
+		// 所有操作成功,提交事务
+		_ = tx.Commit()
+
+	}
+
+	return &types.BaseMsgResp{Msg: errormsg.UpdateSuccess}, nil
+}

+ 96 - 0
internal/logic/label_relationship/set_whatsapp_contact_label_logic.go

@@ -0,0 +1,96 @@
+package label_relationship
+
+import (
+	"context"
+	"wechat-api/ent/contact"
+	"wechat-api/ent/labelrelationship"
+	"wechat-api/internal/utils/dberrorhandler"
+
+	"wechat-api/internal/svc"
+	"wechat-api/internal/types"
+
+	"github.com/zeromicro/go-zero/core/logx"
+)
+
+type SetWhatsappContactLabelLogic struct {
+	logx.Logger
+	ctx    context.Context
+	svcCtx *svc.ServiceContext
+}
+
+func NewSetWhatsappContactLabelLogic(ctx context.Context, svcCtx *svc.ServiceContext) *SetWhatsappContactLabelLogic {
+	return &SetWhatsappContactLabelLogic{
+		Logger: logx.WithContext(ctx),
+		ctx:    ctx,
+		svcCtx: svcCtx}
+}
+
+func (l *SetWhatsappContactLabelLogic) SetWhatsappContactLabel(req *types.LabelRelationshipsInfo) (*types.BaseMsgResp, error) {
+	organizationId := l.ctx.Value("organizationId").(uint64)
+
+	resp := types.BaseMsgResp{}
+
+	// 开始事务
+	tx, err := l.svcCtx.DB.Tx(context.Background())
+	if err != nil {
+		return nil, dberrorhandler.DefaultEntError(l.Logger, err, req)
+	}
+
+	// 获取联系人信息
+	_, err = tx.Contact.Query().Where(
+		contact.ID(*req.ContactId),
+		contact.OrganizationIDEQ(organizationId),
+		contact.Ctype(2),
+	).Only(l.ctx)
+
+	// 获取联系人当前已关联的标签
+	currentLabelRelationships, err := tx.LabelRelationship.Query().Where(labelrelationship.ContactID(*req.ContactId)).All(l.ctx)
+	if err != nil {
+		_ = tx.Rollback()
+		return nil, dberrorhandler.DefaultEntError(l.Logger, err, req)
+	}
+
+	// 提取当前标签ID
+	var currentLabelIds []uint64
+	for _, relationship := range currentLabelRelationships {
+		currentLabelIds = append(currentLabelIds, relationship.LabelID)
+	}
+
+	// 对比新旧标签ID,找出需要新增和移除的标签
+	addLabelIds, removeLabelIds := compareLabelIds(req.LabelIds, currentLabelIds)
+	l.Logger.Infof("addLabelIds=%v, removeLabelIds=%v\n", addLabelIds, removeLabelIds)
+
+	// 如果 req.UpdateType 为空,或 req.UpdateType 的值为 “all” 时
+	if req.UpdateType == nil || *req.UpdateType == "all" {
+		// 删除需要移除的标签关系
+		l.Logger.Errorf("------------------------removeLabelIds--------------------------- %+v\n", removeLabelIds)
+		for _, id := range removeLabelIds {
+			_, err := tx.LabelRelationship.
+				Delete().
+					Where(
+						labelrelationship.ContactID(*req.ContactId),
+						labelrelationship.LabelID(id),
+					).
+				Exec(l.ctx)
+			if err != nil {
+				_ = tx.Rollback()
+				return nil, dberrorhandler.DefaultEntError(l.Logger, err, req)
+			}
+		}
+	}
+
+	// 创建需要新增的标签关系
+	l.Logger.Errorf("------------------------addLabelIds--------------------------- %+v\n", addLabelIds)
+	for _, id := range addLabelIds {
+		_, _ = tx.LabelRelationship.Create().
+			SetLabelID(id).
+			SetContactID(*req.ContactId).
+			SetOrganizationID(organizationId).
+			Save(l.ctx)
+		//if err != nil {
+		//	return nil, dberrorhandler.DefaultEntError(l.Logger, err, req)
+		//}
+	}
+
+	return &resp, nil
+}

+ 2 - 1
internal/logic/whatsapp/list_whatsapp_template_logic.go

@@ -25,7 +25,8 @@ func NewListWhatsappTemplateLogic(ctx context.Context, svcCtx *svc.ServiceContex
 
 func (l *ListWhatsappTemplateLogic) ListWhatsappTemplate(req *types.ListTemplateReq) (*types.ListTemplateResp, error) {
 	resp := types.ListTemplateResp{}
-	result, err := aliyun.ListChatappTemplate(req.Name, req.Language, req.AuditStatus, req.TemplateType, req.Code, req.Page, req.PageSize)
+	result, err := aliyun.ListChatappTemplate(req.WaId, req.Name, req.Language, req.AuditStatus,
+		req.TemplateType, req.Code, req.Page, req.PageSize)
 	l.Logger.Infof("result=%v err=%v\n", result, err)
 
 	if err != nil {

+ 52 - 1
internal/types/types.go

@@ -795,7 +795,17 @@ type ContactInfo struct {
 	// 组织ID
 	OrganizationId *uint64 `json:"organizationId,optional"`
 	// 是否在黑名单中
-	IsInBlockList *bool `json:"isInBlockList,optional"`
+	IsInBlockList *bool   `json:"isInBlockList,optional"`
+	Ctype         *uint64 `json:"ctype,optional"`
+	Cname         *string `json:"cname,optional"`
+	Csex          *int    `json:"csex,optional"`
+	Cage          *int    `json:"cage,optional"`
+	Carea         *string `json:"carea,optional"`
+	Cmobile       *string `json:"cmobile,optional"`
+	Cbirtyday     *string `json:"cbirtyday,optional"`
+	Cbirtharea    *string `json:"cbirtharea,optional"`
+	CidcardNo     *string `json:"cidcardNo,optional"`
+	Ctitle        *string `json:"ctitle,optional"`
 }
 
 // The response data of label information | Label信息
@@ -818,6 +828,8 @@ type LabelInfo struct {
 	OrganizationId *uint64 `json:"organizationId,optional"`
 	// Label Relationships | 标签关系
 	LabelRelationships []LabelRelationshipInfo `json:"labelRelationships,optional"`
+	// 内容类型:1-微信 2-whatsapp
+	Ctype *uint64 `json:"ctype,optional"`
 }
 
 // The response data of label relationship information | LabelRelationship信息
@@ -1012,6 +1024,42 @@ type ChangeBlockListReq struct {
 	Ai        *bool  `json:"ai,optional"`
 }
 
+// swagger:model ImportWhatsappContactReq
+type ImportWhatsappContactReq struct {
+	File *string `form:"file,optional"`
+}
+
+// swagger:model WhatsappContactListReq
+type WhatsappContactListReq struct {
+	PageInfo
+	// 标签ID列表
+	LabelIDs []uint64 `json:"labelIDs,optional"`
+	// 电话
+	Phone *string `json:"phone,optional"`
+	// 名称
+	Name *string `json:"name,optional"`
+}
+
+// swagger:model CreateWhatsappContactReq
+type CreateWhatsappContactReq struct {
+	BaseIDInfo
+	// 国家区号
+	Cc    *string `json:"cc"`
+	Phone *string `json:"phone"`
+	// 备注名
+	Markname   *string `json:"markname,optional"`
+	Ctype      *uint64 `json:"ctype,optional"`
+	Cname      *string `json:"cname,optional"`
+	Csex       *int    `json:"csex,optional"`
+	Cage       *int    `json:"cage,optional"`
+	Carea      *string `json:"carea,optional"`
+	Cmobile    *string `json:"cmobile,optional"`
+	Cbirtyday  *string `json:"cbirtyday,optional"`
+	Cbirtharea *string `json:"cbirtharea,optional"`
+	CidcardNo  *string `json:"cidcardNo,optional"`
+	Ctitle     *string `json:"ctitle,optional"`
+}
+
 // The response data of message information | Message信息
 // swagger:model MessageInfo
 type MessageInfo struct {
@@ -1874,6 +1922,8 @@ type BatchMsgInfo struct {
 	GroupLabels []uint64 `json:"groupLabels,optional"`
 	// 标签列表
 	Type *int32 `json:"type,optional"`
+	// 内容类型:1-微信 2-whatsapp
+	Ctype *uint64 `json:"ctype,optional"`
 }
 
 // The response data of batch msg list | BatchMsg列表数据
@@ -3787,6 +3837,7 @@ type ListTemplateReq struct {
 	AuditStatus  string `json:"auditStatus,optional"`
 	TemplateType string `json:"templateType,optional"`
 	Code         string `json:"code,optional"`
+	WaId         string `json:"waId,optional"`
 }
 
 // swagger:model listTemplateResp

この差分においてかなりの量のファイルが変更されているため、一部のファイルを表示していません