jimmyyem 2 luni în urmă
părinte
comite
aab880f955
60 a modificat fișierele cu 6486 adăugiri și 626 ștergeri
  1. 299 177
      crontask/compute_statistic.go
  2. 1 0
      desc/all.api
  3. 10 2
      desc/wechat/dashboard.api
  4. 85 0
      desc/wechat/label_tagging.api
  5. 8 0
      desc/wechat/sop_stage.api
  6. 28 0
      desc/wechat/wx.api
  7. 13 0
      desc/wechat/xiaoice.api
  8. 149 8
      ent/client.go
  9. 2 0
      ent/ent.go
  10. 12 0
      ent/hook/hook.go
  11. 30 0
      ent/intercept/intercept.go
  12. 1 12
      ent/labelrelationship.go
  13. 0 16
      ent/labelrelationship/labelrelationship.go
  14. 0 55
      ent/labelrelationship/where.go
  15. 2 89
      ent/labelrelationship_create.go
  16. 4 68
      ent/labelrelationship_update.go
  17. 201 0
      ent/labeltagging.go
  18. 128 0
      ent/labeltagging/labeltagging.go
  19. 450 0
      ent/labeltagging/where.go
  20. 1098 0
      ent/labeltagging_create.go
  21. 88 0
      ent/labeltagging_delete.go
  22. 526 0
      ent/labeltagging_query.go
  23. 607 0
      ent/labeltagging_update.go
  24. 27 5
      ent/migrate/schema.go
  25. 983 74
      ent/mutation.go
  26. 82 0
      ent/pagination.go
  27. 3 0
      ent/predicate/predicate.go
  28. 38 4
      ent/runtime/runtime.go
  29. 0 3
      ent/schema/label_relationship.go
  30. 57 0
      ent/schema/label_tagging.go
  31. 192 24
      ent/set_not_nil.go
  32. 3 0
      ent/tx.go
  33. 44 0
      internal/handler/Wx/get_select_wx_list_handler.go
  34. 44 0
      internal/handler/label_tagging/create_label_tagging_handler.go
  35. 44 0
      internal/handler/label_tagging/delete_label_tagging_handler.go
  36. 44 0
      internal/handler/label_tagging/get_label_tagging_by_id_handler.go
  37. 44 0
      internal/handler/label_tagging/get_label_tagging_list_handler.go
  38. 44 0
      internal/handler/label_tagging/update_label_tagging_handler.go
  39. 50 0
      internal/handler/routes.go
  40. 44 0
      internal/handler/sop_stage/sop_stage_copy_handler.go
  41. 44 0
      internal/handler/xiaoice/gptbots_chat_handler.go
  42. 65 0
      internal/logic/Wx/get_select_wx_list_logic.go
  43. 7 2
      internal/logic/Wx/get_wx_list_logic.go
  44. 15 9
      internal/logic/Wxhook/get_friends_and_groups_logic.go
  45. 1 1
      internal/logic/Wxhook/logout_logic.go
  46. 8 1
      internal/logic/contact/add_new_friend_logic.go
  47. 2 1
      internal/logic/contact/get_contact_list_logic.go
  48. 165 38
      internal/logic/dashboard/get_charts_logic.go
  49. 41 23
      internal/logic/dashboard/get_wxs_logic.go
  50. 0 1
      internal/logic/label/delete_label_logic.go
  51. 41 0
      internal/logic/label_tagging/create_label_tagging_logic.go
  52. 37 0
      internal/logic/label_tagging/delete_label_tagging_logic.go
  53. 55 0
      internal/logic/label_tagging/get_label_tagging_by_id_logic.go
  54. 69 0
      internal/logic/label_tagging/get_label_tagging_list_logic.go
  55. 41 0
      internal/logic/label_tagging/update_label_tagging_logic.go
  56. 109 0
      internal/logic/sop_stage/sop_stage_copy_logic.go
  57. 13 3
      internal/logic/sop_task/publish_sop_task_logic.go
  58. 12 2
      internal/logic/sop_task/sop_task_copy_logic.go
  59. 175 0
      internal/logic/xiaoice/gptbots_chat_logic.go
  60. 101 8
      internal/types/types.go

+ 299 - 177
crontask/compute_statistic.go

@@ -2,6 +2,7 @@ package crontask
 
 import (
 	"strconv"
+	"strings"
 	"time"
 	"wechat-api/ent"
 	"wechat-api/ent/contact"
@@ -11,7 +12,6 @@ import (
 	"wechat-api/ent/usagedetail"
 	"wechat-api/ent/usagestatisticday"
 	"wechat-api/ent/usagestatistichour"
-	"wechat-api/ent/usagestatisticmonth"
 	"wechat-api/ent/wx"
 )
 
@@ -27,7 +27,9 @@ func (l *CronTask) computeStatistic() {
 
 	wxbotsSet := make(map[uint64][]*ent.Wx)
 	for _, bot := range wxbots {
-		wxbotsSet[bot.OrganizationID] = append(wxbotsSet[bot.OrganizationID], bot)
+		if !strings.HasPrefix(bot.Wxid, "temp-") {
+			wxbotsSet[bot.OrganizationID] = append(wxbotsSet[bot.OrganizationID], bot)
+		}
 	}
 	LabelsCountSet := make(map[uint64][]custom_types.LabelDist)
 
@@ -50,17 +52,20 @@ func (l *CronTask) computeStatistic() {
 	lastHour := currentHour.Add(-time.Hour * 1)
 	lastHourInt, _ := strconv.Atoi(lastHour.Format("2006010215"))
 
+	lc := []custom_types.LabelDist{}
+
+	var allHourAiResponseInt, allHourSopRunInt, allHourFriendCountInt, allHourGroupCountInt, allHourAccountBalanceInt, allHourConsumeTokenInt, allHourActiveUserInt, allHourNewUserInt int
 	for orgID, wxinfos := range wxbotsSet {
 		var orgAiResponseInt, orgSopRunInt, orgFriendCountInt, orgGroupCountInt, orgAccountBalanceInt, orgConsumeTokenInt, orgActiveUserInt, orgNewUserInt int
 		for _, wxinfo := range wxinfos {
-			l.Logger.Infof("开始计算小时数据:%d\n", currentHourInt)
+			l.Logger.Infof("开始计算小时数据:%d\n", lastHourInt)
 
 			// 先判断该账号是否已经统计了小时数据,如果已经统计了,就不需要再统计了
 			var aiResponseInt, sopRunInt, friendCountInt, groupCountInt, accountBalanceInt, consumeTokenInt, activeUserInt, newUserInt int
 			hourDataCount, _ := l.svcCtx.DB.UsageStatisticHour.Query().Where(
 				usagestatistichour.Type(1),
 				usagestatistichour.BotID(wxinfo.Wxid),
-				usagestatistichour.Addtime(uint64(currentHourInt)),
+				usagestatistichour.Addtime(uint64(lastHourInt)),
 			).Count(l.ctx)
 			if hourDataCount > 0 {
 				continue
@@ -84,6 +89,7 @@ func (l *CronTask) computeStatistic() {
 			).Count(l.ctx)
 			aiResponseInt = sopresp + airesp
 			orgAiResponseInt += aiResponseInt
+			allHourAiResponseInt += aiResponseInt
 
 			// SOP执行次数:SOP阶段和节点的执行次数。
 			sopRunInt, _ = l.svcCtx.DB.MessageRecords.Query().Where(
@@ -95,6 +101,7 @@ func (l *CronTask) computeStatistic() {
 				messagerecords.CreatedAtLT(currentHour),
 			).Count(l.ctx)
 			orgSopRunInt += sopRunInt
+			allHourSopRunInt += sopRunInt
 
 			// 好友总数:contact 表中 type=1
 			friendCountInt, _ = l.svcCtx.DB.Contact.Query().Where(
@@ -102,6 +109,7 @@ func (l *CronTask) computeStatistic() {
 				contact.WxWxid(wxinfo.Wxid),
 			).Count(l.ctx)
 			orgFriendCountInt += friendCountInt
+			allHourFriendCountInt += friendCountInt
 
 			// 群总数:contact 表中 type=2
 			groupCountInt, _ = l.svcCtx.DB.Contact.Query().Where(
@@ -109,6 +117,7 @@ func (l *CronTask) computeStatistic() {
 				contact.WxWxid(wxinfo.Wxid),
 			).Count(l.ctx)
 			orgGroupCountInt += groupCountInt
+			allHourGroupCountInt += groupCountInt
 
 			// 消耗Token数:usage_detail 表
 			consumeTokenInt, _ = l.svcCtx.DB.UsageDetail.Query().Where(
@@ -118,19 +127,23 @@ func (l *CronTask) computeStatistic() {
 				usagedetail.CreatedAtLT(currentHour),
 			).Aggregate(ent.Sum("total_tokens")).Int(l.ctx)
 			orgConsumeTokenInt += consumeTokenInt
+			allHourConsumeTokenInt += consumeTokenInt
 
 			// 账户余额
 			accountBalanceInt = 0
 			orgAccountBalanceInt = 0
+			allHourAccountBalanceInt = 0
 
 			// 活跃好友:usage_detail 表 type = 1
-			activeUserInt, _ = l.svcCtx.DB.UsageDetail.Query().Where(
+			activeUsers, _ := l.svcCtx.DB.UsageDetail.Query().Where(
 				usagedetail.Type(1),
 				usagedetail.BotID(wxinfo.Wxid),
 				usagedetail.CreatedAtGTE(lastHour),
 				usagedetail.CreatedAtLT(currentHour),
-			).GroupBy(usagedetail.FieldReceiverID).Int(l.ctx)
+			).GroupBy(usagedetail.FieldReceiverID).Strings(l.ctx)
+			activeUserInt = len(activeUsers)
 			orgActiveUserInt += activeUserInt
+			allHourActiveUserInt += activeUserInt
 
 			lastHourData, _ := l.svcCtx.DB.UsageStatisticHour.Query().Where(
 				usagestatistichour.AddtimeEQ(uint64(lastHourInt)),
@@ -139,11 +152,12 @@ func (l *CronTask) computeStatistic() {
 			).First(l.ctx)
 
 			if lastHourData == nil {
-				newUserInt = friendCountInt
+				newUserInt = 0
 			} else {
-				newUserInt = int(lastHourData.TotalFriend) - friendCountInt
+				newUserInt = friendCountInt - int(lastHourData.TotalFriend)
 			}
 			orgNewUserInt += newUserInt
+			allHourNewUserInt += newUserInt
 
 			_, err := l.svcCtx.DB.UsageStatisticHour.Create().
 				SetType(1).
@@ -157,7 +171,8 @@ func (l *CronTask) computeStatistic() {
 				SetConsumeToken(uint64(consumeTokenInt)).
 				SetActiveUser(uint64(activeUserInt)).
 				SetNewUser(int64(newUserInt)).
-				SetAddtime(uint64(currentHourInt)).
+				SetAddtime(uint64(lastHourInt)).
+				SetLabelDist(lc).
 				Save(l.ctx)
 			l.Errorf("save hour data error:%v \n", err)
 		}
@@ -165,15 +180,15 @@ func (l *CronTask) computeStatistic() {
 		hourDataCount, _ := l.svcCtx.DB.UsageStatisticHour.Query().Where(
 			usagestatistichour.Type(1),
 			usagestatistichour.OrganizationID(orgID),
-			usagestatistichour.BotIDIsNil(),
-			usagestatistichour.Addtime(uint64(currentHourInt)),
+			usagestatistichour.BotID(""),
+			usagestatistichour.Addtime(uint64(lastHourInt)),
 		).Count(l.ctx)
 		if hourDataCount > 0 {
 			continue
 		}
 
-		var LabelsCount []custom_types.LabelDist
-		err := l.svcCtx.DB.LabelRelationship.Query().Where(labelrelationship.OrganizationIDEQ(orgID), labelrelationship.DeletedAtIsNil()).GroupBy(labelrelationship.FieldLabelID).Aggregate(ent.Count()).Scan(l.ctx, &LabelsCount)
+		LabelsCount := []custom_types.LabelDist{}
+		err := l.svcCtx.DB.LabelRelationship.Query().Where(labelrelationship.OrganizationIDEQ(orgID)).GroupBy(labelrelationship.FieldLabelID).Aggregate(ent.Count()).Scan(l.ctx, &LabelsCount)
 		l.Errorf("save hour data error:%v \n", err)
 		LabelsCountSet[orgID] = LabelsCount
 
@@ -188,44 +203,61 @@ func (l *CronTask) computeStatistic() {
 			SetConsumeToken(uint64(orgConsumeTokenInt)).
 			SetActiveUser(uint64(orgActiveUserInt)).
 			SetNewUser(int64(orgNewUserInt)).
-			SetAddtime(uint64(currentHourInt)).
+			SetAddtime(uint64(lastHourInt)).
 			SetNotNilLabelDist(LabelsCount).
 			Save(l.ctx)
 		l.Errorf("save hour data error:%v \n", err)
 	}
 
+	// 先判断该租户是否已经统计了小时数据,如果已经统计了,就不需要再统计了
+	hourDataCount, _ := l.svcCtx.DB.UsageStatisticHour.Query().Where(
+		usagestatistichour.Type(1),
+		usagestatistichour.OrganizationID(0),
+		usagestatistichour.BotID(""),
+		usagestatistichour.Addtime(uint64(lastHourInt)),
+	).Count(l.ctx)
+	if hourDataCount == 0 {
+		_, err = l.svcCtx.DB.UsageStatisticHour.Create().
+			SetType(1).
+			SetOrganizationID(0).
+			SetAiResponse(uint64(allHourAiResponseInt)).
+			SetSopRun(uint64(allHourSopRunInt)).
+			SetTotalFriend(uint64(allHourFriendCountInt)).
+			SetTotalGroup(uint64(allHourGroupCountInt)).
+			SetAccountBalance(uint64(allHourAccountBalanceInt)).
+			SetConsumeToken(uint64(allHourConsumeTokenInt)).
+			SetActiveUser(uint64(allHourActiveUserInt)).
+			SetNewUser(int64(allHourNewUserInt)).
+			SetAddtime(uint64(lastHourInt)).
+			SetLabelDist(lc).
+			Save(l.ctx)
+		l.Errorf("save hour data error:%v \n", err)
+	}
+
 	/*
 		计算日数据
 		----------------------------------------------------------------------------------------------------------
 	*/
-	dayStr := time.Now().Format("20060102")
-	day, _ := strconv.Atoi(dayStr)
+	//dayStr := time.Now().Format("20060102")
+	//day, _ := strconv.Atoi(dayStr)
 
 	// 获取昨天的第一小时
 	yesterday := now.AddDate(0, 0, -1)
-	yesterdayFirstHour := time.Date(yesterday.Year(), yesterday.Month(), now.Day(), 0, 0, 0, 0, now.Location())
-	yesterdayFirstHourInt, _ := strconv.Atoi(yesterdayFirstHour.Format("20060102"))
+	yesterdayFirstHour := time.Date(yesterday.Year(), yesterday.Month(), yesterday.Day(), 0, 0, 0, 0, now.Location())
+	yesterdayInt, _ := strconv.Atoi(yesterdayFirstHour.Format("20060102"))
+	yesterdayFirstHourInt, _ := strconv.Atoi(yesterdayFirstHour.Format("2006010215"))
 
 	// 获取昨天的最后一小时
 	yesterdayLastHour := time.Date(now.Year(), now.Month(), now.Day(), 0, 0, 0, 0, now.Location())
-	yesterdayLastHourInt, _ := strconv.Atoi(yesterdayLastHour.Format("20060102"))
+	yesterdayLastHourInt, _ := strconv.Atoi(yesterdayLastHour.Format("2006010215"))
 
+	var allDayAiResponseInt, allDaySopRunInt, allDayFriendCountInt, allDayGroupCountInt, allDayAccountBalanceInt, allDayConsumeTokenInt, allDayActiveUserInt uint64
+	var allDayNewUserInt int64
 	for orgID, wxinfos := range wxbotsSet {
 		var orgAiResponseInt, orgSopRunInt, orgFriendCountInt, orgGroupCountInt, orgAccountBalanceInt, orgConsumeTokenInt, orgActiveUserInt uint64
 		var orgNewUserInt int64
 		for _, wxinfo := range wxinfos {
-			l.Logger.Infof("开始计算日数据:%d\n", day)
-			// 先判断该账号是否已经统计了日数据,如果已经统计了,就不需要再统计了
-			dayDataCount, _ := l.svcCtx.DB.UsageStatisticDay.Query().Where(
-				usagestatisticday.Type(1),
-				usagestatisticday.BotID(wxinfo.Wxid),
-				usagestatisticday.Addtime(uint64(day)),
-			).Count(l.ctx)
-
-			// 如果添加过了就略过
-			if dayDataCount > 0 {
-				continue
-			}
+			l.Logger.Infof("开始计算日数据:%d\n", yesterdayInt)
 
 			hourDataBatch, _ := l.svcCtx.DB.UsageStatisticHour.Query().Where(
 				usagestatistichour.Type(1),
@@ -234,18 +266,31 @@ func (l *CronTask) computeStatistic() {
 				usagestatistichour.AddtimeLT(uint64(yesterdayLastHourInt)),
 			).All(l.ctx)
 
+			if hourDataBatch == nil {
+				continue
+			}
 			var aiResponse, sopRun, totalFriend, totalGroup, accountBalance, consumeToken, activeUser uint64
 			var newUser int64
 			for _, hourData := range hourDataBatch {
 				aiResponse += hourData.AiResponse
 				sopRun += hourData.SopRun
-				totalFriend += hourData.TotalFriend
-				totalGroup += hourData.TotalGroup
-				accountBalance += hourData.AccountBalance
+				totalFriend = hourData.TotalFriend
+				totalGroup = hourData.TotalGroup
+				accountBalance = hourData.AccountBalance
 				consumeToken += hourData.ConsumeToken
-				activeUser += hourData.ActiveUser
+				//activeUser += hourData.ActiveUser
 				newUser += hourData.NewUser
 			}
+
+			// 活跃好友:usage_detail 表 type = 1
+			activeUsers, _ := l.svcCtx.DB.UsageDetail.Query().Where(
+				usagedetail.Type(1),
+				usagedetail.BotID(wxinfo.Wxid),
+				usagedetail.CreatedAtGTE(yesterdayFirstHour),
+				usagedetail.CreatedAtLT(yesterdayLastHour),
+			).GroupBy(usagedetail.FieldReceiverID).Strings(l.ctx)
+			activeUser = uint64(len(activeUsers))
+
 			orgAiResponseInt += aiResponse
 			orgSopRunInt += sopRun
 			orgFriendCountInt += totalFriend
@@ -255,55 +300,102 @@ func (l *CronTask) computeStatistic() {
 			orgActiveUserInt += activeUser
 			orgNewUserInt += newUser
 
-			_, err := l.svcCtx.DB.UsageStatisticDay.Create().
-				SetAddtime(uint64(day)).
-				SetType(1).
-				SetBotID(wxinfo.Wxid).
-				SetOrganizationID(wxinfo.OrganizationID).
-				SetAiResponse(aiResponse).
-				SetSopRun(sopRun).
-				SetTotalFriend(totalFriend).
-				SetTotalGroup(totalGroup).
-				SetAccountBalance(accountBalance).
-				SetConsumeToken(consumeToken).
-				SetActiveUser(activeUser).
-				SetNewUser(newUser).
-				Save(l.ctx)
-			if err != nil {
-				l.Errorf("create day data error:%v \n", err)
-				continue
+			allDayAiResponseInt += aiResponse
+			allDaySopRunInt += sopRun
+			allDayFriendCountInt += totalFriend
+			allDayGroupCountInt += totalGroup
+			allDayAccountBalanceInt += accountBalance
+			allDayConsumeTokenInt += consumeToken
+			allDayActiveUserInt += activeUser
+			allDayNewUserInt += newUser
+
+			// 先判断该账号是否已经统计了日数据,如果已经统计了,就不需要再统计了
+			dayDataCount, _ := l.svcCtx.DB.UsageStatisticDay.Query().Where(
+				usagestatisticday.Type(1),
+				usagestatisticday.BotID(wxinfo.Wxid),
+				usagestatisticday.Addtime(uint64(yesterdayInt)),
+			).Count(l.ctx)
+
+			// 如果添加过了就略过
+			if dayDataCount == 0 && yesterdayLastHourInt <= currentHourInt {
+				_, err := l.svcCtx.DB.UsageStatisticDay.Create().
+					SetAddtime(uint64(yesterdayInt)).
+					SetType(1).
+					SetBotID(wxinfo.Wxid).
+					SetOrganizationID(wxinfo.OrganizationID).
+					SetAiResponse(aiResponse).
+					SetSopRun(sopRun).
+					SetTotalFriend(totalFriend).
+					SetTotalGroup(totalGroup).
+					SetAccountBalance(accountBalance).
+					SetConsumeToken(consumeToken).
+					SetActiveUser(activeUser).
+					SetNewUser(newUser).
+					SetLabelDist(lc).
+					Save(l.ctx)
+				if err != nil {
+					l.Errorf("create day data error:%v \n", err)
+					continue
+				}
 			}
 		}
 		// 先判断该租户是否已经统计了日数据,如果已经统计了,就不需要再统计了
 		dayDataCount, _ := l.svcCtx.DB.UsageStatisticDay.Query().Where(
 			usagestatisticday.Type(1),
 			usagestatisticday.OrganizationID(orgID),
-			usagestatisticday.BotIDIsNil(),
-			usagestatisticday.Addtime(uint64(day)),
+			usagestatisticday.BotID(""),
+			usagestatisticday.Addtime(uint64(yesterdayInt)),
 		).Count(l.ctx)
 
 		// 如果添加过了就略过
-		if dayDataCount > 0 {
-			continue
+		if dayDataCount == 0 && yesterdayLastHourInt <= currentHourInt {
+			_, err := l.svcCtx.DB.UsageStatisticDay.Create().
+				SetAddtime(uint64(yesterdayInt)).
+				SetType(1).
+				SetOrganizationID(orgID).
+				SetAiResponse(orgAiResponseInt).
+				SetSopRun(orgSopRunInt).
+				SetTotalFriend(orgFriendCountInt).
+				SetTotalGroup(orgGroupCountInt).
+				SetAccountBalance(orgAccountBalanceInt).
+				SetConsumeToken(orgConsumeTokenInt).
+				SetActiveUser(orgActiveUserInt).
+				SetNewUser(orgNewUserInt).
+				SetNotNilLabelDist(LabelsCountSet[orgID]).
+				Save(l.ctx)
+			if err != nil {
+				l.Errorf("create day data error:%v \n", err)
+				continue
+			}
 		}
+	}
 
-		_, err := l.svcCtx.DB.UsageStatisticDay.Create().
-			SetAddtime(uint64(day)).
+	// 先判断该租户是否已经统计了日数据,如果已经统计了,就不需要再统计了
+	dayDataCount, _ := l.svcCtx.DB.UsageStatisticDay.Query().Where(
+		usagestatisticday.Type(1),
+		usagestatisticday.OrganizationID(0),
+		usagestatisticday.BotID(""),
+		usagestatisticday.Addtime(uint64(yesterdayInt)),
+	).Count(l.ctx)
+
+	// 如果添加过了就略过
+	if dayDataCount == 0 && yesterdayLastHourInt <= currentHourInt {
+		_, err = l.svcCtx.DB.UsageStatisticDay.Create().
+			SetAddtime(uint64(yesterdayInt)).
 			SetType(1).
-			SetOrganizationID(orgID).
-			SetAiResponse(orgAiResponseInt).
-			SetSopRun(orgSopRunInt).
-			SetTotalFriend(orgFriendCountInt).
-			SetTotalGroup(orgGroupCountInt).
-			SetAccountBalance(orgAccountBalanceInt).
-			SetConsumeToken(orgConsumeTokenInt).
-			SetActiveUser(orgActiveUserInt).
-			SetNewUser(orgNewUserInt).
-			SetNotNilLabelDist(LabelsCountSet[orgID]).
+			SetOrganizationID(0).
+			SetAiResponse(allDayAiResponseInt).
+			SetSopRun(allDaySopRunInt).
+			SetTotalFriend(allDayFriendCountInt).
+			SetTotalGroup(allDayGroupCountInt).
+			SetAccountBalance(allDayAccountBalanceInt).
+			SetConsumeToken(allDayConsumeTokenInt).
+			SetActiveUser(allDayActiveUserInt).
+			SetNewUser(allDayNewUserInt).
+			SetLabelDist(lc).
 			Save(l.ctx)
 		if err != nil {
 			l.Errorf("create day data error:%v \n", err)
-			continue
 		}
 	}
 
@@ -313,114 +405,144 @@ func (l *CronTask) computeStatistic() {
 		2. 挨个遍历他的 bot_id ,再查询他的 bot_id 相关的参数
 		----------------------------------------------------------------------------------------------------------
 	*/
-	monthStr := time.Now().Format("200601")
-	month, _ := strconv.Atoi(monthStr)
-
-	for orgID, wxinfos := range wxbotsSet {
-		var orgAiResponseInt, orgSopRunInt, orgFriendCountInt, orgGroupCountInt, orgAccountBalanceInt, orgConsumeTokenInt, orgActiveUserInt uint64
-		var orgNewUserInt int64
-		for _, wxinfo := range wxinfos {
-			l.Logger.Infof("开始计算月数据:%d\n", month)
-
-			// 获取上月的第一天
-			monthFirstDay := time.Date(now.Year(), now.Month()-1, 1, 0, 0, 0, 0, now.Location())
-			monthFirstDayInt, _ := strconv.Atoi(monthFirstDay.Format("20060102"))
-
-			// 获取上月的最后一天
-			monthLastDay := time.Date(now.Year(), now.Month(), 1, 0, 0, 0, 0, now.Location())
-			monthLastDayInt, _ := strconv.Atoi(monthLastDay.Format("20060102"))
-
-			// 先判断该账号是否已经统计了月数据,如果已经统计了,就不需要再统计了
-			monthDataCount, _ := l.svcCtx.DB.UsageStatisticMonth.Query().Where(
-				usagestatisticmonth.Type(1),
-				usagestatisticmonth.BotID(wxinfo.Wxid),
-				usagestatisticmonth.Addtime(uint64(month)),
-			).Count(l.ctx)
-
-			// 如果添加过了就略过
-			if monthDataCount > 0 {
-				continue
-			}
-
-			dayDataBatch, _ := l.svcCtx.DB.UsageStatisticDay.Query().Where(
-				usagestatisticday.Type(1),
-				usagestatisticday.BotID(wxinfo.Wxid),
-				usagestatisticday.AddtimeGTE(uint64(monthFirstDayInt)),
-				usagestatisticday.AddtimeLT(uint64(monthLastDayInt)),
-			).All(l.ctx)
-
-			var aiResponse, sopRun, totalFriend, totalGroup, accountBalance, consumeToken, activeUser uint64
-			var newUser int64
-			for _, dayData := range dayDataBatch {
-				aiResponse += dayData.AiResponse
-				sopRun += dayData.SopRun
-				totalFriend += dayData.TotalFriend
-				totalGroup += dayData.TotalGroup
-				accountBalance += dayData.AccountBalance
-				consumeToken += dayData.ConsumeToken
-				activeUser += dayData.ActiveUser
-				newUser += dayData.NewUser
-			}
-			orgAiResponseInt += aiResponse
-			orgSopRunInt += sopRun
-			orgFriendCountInt += totalFriend
-			orgGroupCountInt += totalGroup
-			orgAccountBalanceInt += accountBalance
-			orgConsumeTokenInt += consumeToken
-			orgActiveUserInt += activeUser
-			orgNewUserInt += newUser
-
-			_, err := l.svcCtx.DB.UsageStatisticMonth.Create().
-				SetAddtime(uint64(month)).
-				SetType(1).
-				SetBotID(wxinfo.Wxid).
-				SetOrganizationID(wxinfo.OrganizationID).
-				SetAiResponse(aiResponse).
-				SetSopRun(sopRun).
-				SetTotalFriend(totalFriend).
-				SetTotalGroup(totalGroup).
-				SetAccountBalance(accountBalance).
-				SetConsumeToken(consumeToken).
-				SetActiveUser(activeUser).
-				SetNewUser(newUser).
-				Save(l.ctx)
-			if err != nil {
-				l.Errorf("create month data error:%v \n", err)
-				continue
-			}
-		}
-		// 先判断该租户是否已经统计了月数据,如果已经统计了,就不需要再统计了
-		monthDataCount, _ := l.svcCtx.DB.UsageStatisticMonth.Query().Where(
-			usagestatisticmonth.Type(1),
-			usagestatisticmonth.OrganizationID(orgID),
-			usagestatisticmonth.BotIDIsNil(),
-			usagestatisticmonth.Addtime(uint64(month)),
-		).Count(l.ctx)
-
-		// 如果添加过了就略过
-		if monthDataCount > 0 {
-			continue
-		}
-
-		_, err := l.svcCtx.DB.UsageStatisticMonth.Create().
-			SetAddtime(uint64(month)).
-			SetType(1).
-			SetOrganizationID(orgID).
-			SetAiResponse(orgAiResponseInt).
-			SetSopRun(orgSopRunInt).
-			SetTotalFriend(orgFriendCountInt).
-			SetTotalGroup(orgGroupCountInt).
-			SetAccountBalance(orgAccountBalanceInt).
-			SetConsumeToken(orgConsumeTokenInt).
-			SetActiveUser(orgActiveUserInt).
-			SetNewUser(orgNewUserInt).
-			SetNotNilLabelDist(LabelsCountSet[orgID]).
-			Save(l.ctx)
-		if err != nil {
-			l.Errorf("create month data error:%v \n", err)
-			continue
-		}
-	}
+	//monthStr := time.Now().Format("200601")
+	//month, _ := strconv.Atoi(monthStr)
+	//
+	//var allMonthAiResponseInt, allMonthSopRunInt, allMonthFriendCountInt, allMonthGroupCountInt, allMonthAccountBalanceInt, allMonthConsumeTokenInt, allMonthActiveUserInt uint64
+	//var allMonthNewUserInt int64
+	//for orgID, wxinfos := range wxbotsSet {
+	//	var orgAiResponseInt, orgSopRunInt, orgFriendCountInt, orgGroupCountInt, orgAccountBalanceInt, orgConsumeTokenInt, orgActiveUserInt uint64
+	//	var orgNewUserInt int64
+	//	for _, wxinfo := range wxinfos {
+	//		l.Logger.Infof("开始计算月数据:%d\n", month)
+	//
+	//		// 获取上月的第一天
+	//		monthFirstDay := time.Date(now.Year(), now.Month()-1, 1, 0, 0, 0, 0, now.Location())
+	//		monthFirstDayInt, _ := strconv.Atoi(monthFirstDay.Format("20060102"))
+	//
+	//		// 获取上月的最后一天
+	//		monthLastDay := time.Date(now.Year(), now.Month(), 1, 0, 0, 0, 0, now.Location())
+	//		monthLastDayInt, _ := strconv.Atoi(monthLastDay.Format("20060102"))
+	//
+	//		// 先判断该账号是否已经统计了月数据,如果已经统计了,就不需要再统计了
+	//		monthDataCount, _ := l.svcCtx.DB.UsageStatisticMonth.Query().Where(
+	//			usagestatisticmonth.Type(1),
+	//			usagestatisticmonth.BotID(wxinfo.Wxid),
+	//			usagestatisticmonth.Addtime(uint64(month)),
+	//		).Count(l.ctx)
+	//
+	//		// 如果添加过了就略过
+	//		if monthDataCount > 0 {
+	//			continue
+	//		}
+	//
+	//		dayDataBatch, _ := l.svcCtx.DB.UsageStatisticDay.Query().Where(
+	//			usagestatisticday.Type(1),
+	//			usagestatisticday.BotID(wxinfo.Wxid),
+	//			usagestatisticday.AddtimeGTE(uint64(monthFirstDayInt)),
+	//			usagestatisticday.AddtimeLT(uint64(monthLastDayInt)),
+	//		).All(l.ctx)
+	//
+	//		var aiResponse, sopRun, totalFriend, totalGroup, accountBalance, consumeToken, activeUser uint64
+	//		var newUser int64
+	//		for _, dayData := range dayDataBatch {
+	//			aiResponse += dayData.AiResponse
+	//			sopRun += dayData.SopRun
+	//			totalFriend += dayData.TotalFriend
+	//			totalGroup += dayData.TotalGroup
+	//			accountBalance += dayData.AccountBalance
+	//			consumeToken += dayData.ConsumeToken
+	//			activeUser += dayData.ActiveUser
+	//			newUser += dayData.NewUser
+	//		}
+	//		orgAiResponseInt += aiResponse
+	//		orgSopRunInt += sopRun
+	//		orgFriendCountInt += totalFriend
+	//		orgGroupCountInt += totalGroup
+	//		orgAccountBalanceInt += accountBalance
+	//		orgConsumeTokenInt += consumeToken
+	//		orgActiveUserInt += activeUser
+	//		orgNewUserInt += newUser
+	//
+	//		allMonthAiResponseInt += aiResponse
+	//		allMonthSopRunInt += sopRun
+	//		allMonthFriendCountInt += totalFriend
+	//		allMonthGroupCountInt += totalGroup
+	//		allMonthAccountBalanceInt += accountBalance
+	//		allMonthConsumeTokenInt += consumeToken
+	//		allMonthActiveUserInt += activeUser
+	//		allMonthNewUserInt += newUser
+	//
+	//		_, err := l.svcCtx.DB.UsageStatisticMonth.Create().
+	//			SetAddtime(uint64(month)).
+	//			SetType(1).
+	//			SetBotID(wxinfo.Wxid).
+	//			SetOrganizationID(wxinfo.OrganizationID).
+	//			SetAiResponse(aiResponse).
+	//			SetSopRun(sopRun).
+	//			SetTotalFriend(totalFriend).
+	//			SetTotalGroup(totalGroup).
+	//			SetAccountBalance(accountBalance).
+	//			SetConsumeToken(consumeToken).
+	//			SetActiveUser(activeUser).
+	//			SetNewUser(newUser).
+	//			SetLabelDist(lc).
+	//			Save(l.ctx)
+	//		if err != nil {
+	//			l.Errorf("create month data error:%v \n", err)
+	//			continue
+	//		}
+	//	}
+	//	// 先判断该租户是否已经统计了月数据,如果已经统计了,就不需要再统计了
+	//	monthDataCount, _ := l.svcCtx.DB.UsageStatisticMonth.Query().Where(
+	//		usagestatisticmonth.Type(1),
+	//		usagestatisticmonth.OrganizationID(orgID),
+	//		usagestatisticmonth.BotIDIsNil(),
+	//		usagestatisticmonth.Addtime(uint64(month)),
+	//	).Count(l.ctx)
+	//
+	//	// 如果添加过了就略过
+	//	if monthDataCount > 0 {
+	//		continue
+	//	}
+	//
+	//	_, err := l.svcCtx.DB.UsageStatisticMonth.Create().
+	//		SetAddtime(uint64(month)).
+	//		SetType(1).
+	//		SetOrganizationID(orgID).
+	//		SetAiResponse(orgAiResponseInt).
+	//		SetSopRun(orgSopRunInt).
+	//		SetTotalFriend(orgFriendCountInt).
+	//		SetTotalGroup(orgGroupCountInt).
+	//		SetAccountBalance(orgAccountBalanceInt).
+	//		SetConsumeToken(orgConsumeTokenInt).
+	//		SetActiveUser(orgActiveUserInt).
+	//		SetNewUser(orgNewUserInt).
+	//		SetNotNilLabelDist(LabelsCountSet[orgID]).
+	//		Save(l.ctx)
+	//	if err != nil {
+	//		l.Errorf("create month data error:%v \n", err)
+	//		continue
+	//	}
+	//}
+	//
+	//_, err = l.svcCtx.DB.UsageStatisticMonth.Create().
+	//	SetAddtime(uint64(month)).
+	//	SetType(1).
+	//	SetOrganizationID(0).
+	//	SetAiResponse(allMonthAiResponseInt).
+	//	SetSopRun(allMonthSopRunInt).
+	//	SetTotalFriend(allMonthFriendCountInt).
+	//	SetTotalGroup(allMonthGroupCountInt).
+	//	SetAccountBalance(allMonthAccountBalanceInt).
+	//	SetConsumeToken(allMonthConsumeTokenInt).
+	//	SetActiveUser(allMonthActiveUserInt).
+	//	SetNewUser(allMonthNewUserInt).
+	//	SetNotNilLabelDist(lc).
+	//	Save(l.ctx)
+	//if err != nil {
+	//	l.Errorf("create month data error:%v \n", err)
+	//}
 
 	finishTime := time.Now()
 	l.Logger.Infof("This process cost %v", finishTime.Sub(startTime).String())

+ 1 - 0
desc/all.api

@@ -6,6 +6,7 @@ import "./wechat/contact.api"
 import "./wechat/message.api"
 import "./wechat/label.api"
 import "./wechat/label_relationship.api"
+import "./wechat/label_tagging.api"
 import "./wechat/sop_task.api"
 import "./wechat/sop_stage.api"
 import "./wechat/sop_node.api"

+ 10 - 2
desc/wechat/dashboard.api

@@ -12,6 +12,8 @@ type (
 
         // 租户id
         OrganizationId  *uint64 `json:"organizationId,optional"`
+
+        Wxid  *string `json:"wxid,optional"`
     }
     ChartsResp {
         BaseDataInfo
@@ -33,16 +35,20 @@ type (
 
     ChartsUint {
         Count uint64 `json:"count"`
-        Rate float32 `json:"rate"`
+        Rate *float32 `json:"rate"`
         Label []string `json:"label"`
         Val []uint64 `json:"val"`
+        LabelText string `json:"labelText"`
+        Tip *string `json:"tip"`
     }
 
     ChartsInt {
         Count int64 `json:"count"`
-        Rate float32 `json:"rate"`
+        Rate *float32 `json:"rate"`
         Label []string `json:"label"`
         Val []int64 `json:"val"`
+        LabelText string `json:"labelText"`
+        Tip *string `json:"tip"`
     }
 
     LabelsData {
@@ -57,6 +63,8 @@ type (
 
         // 租户id
         OrganizationId  *uint64 `json:"organizationId,optional"`
+
+        Wxid  *string `json:"wxid,optional"`
     }
 
     WxResp {

+ 85 - 0
desc/wechat/label_tagging.api

@@ -0,0 +1,85 @@
+import "../base.api"
+
+type (
+    // The data of label tagging information | LabelTagging信息
+    LabelTaggingInfo {
+        BaseIDInfo
+
+        // Status 1: normal 2: ban | 状态 1 正常 2 禁用 
+        Status  *uint8 `json:"status,optional"`
+
+        // 机构 ID
+        OrganizationId  *uint64 `json:"organizationId,optional"`
+
+        // 标签类型:1好友,2群组,3公众号,4企业微信联系人
+        Type  *int `json:"type,optional"`
+
+        // 关键词 
+        Conditions  string `json:"conditions,optional"`
+
+        // 命中后需要打的标签 
+        ActionLabelAdd  []uint64 `json:"actionLabelAdd,optional"`
+
+        // 命中后需要移除的标签 
+        ActionLabelDel  []uint64 `json:"actionLabelDel,optional"`
+
+        LabelAddInfo  []string `json:"labelAddInfo,optional"`
+    }
+
+    // The response data of label tagging list | LabelTagging信息列表数据
+    LabelTaggingListResp {
+        BaseDataInfo
+
+        // The label tagging list data | LabelTagging信息列表数据
+        Data LabelTaggingListInfo `json:"data"`
+    }
+
+    // The label tagging list data | LabelTagging信息列表数据
+    LabelTaggingListInfo {
+        BaseListInfo
+
+        // The label tagging list data | LabelTagging信息列表数据
+        Data  []LabelTaggingInfo  `json:"data"`
+    }
+
+    // Get label tagging list request params | LabelTagging信息列表请求参数
+    LabelTaggingListReq {
+        PageInfo
+    }
+
+    // The label tagging information response | LabelTagging信息返回体
+    LabelTaggingInfoResp {
+        BaseDataInfo
+
+        // label tagging information | LabelTagging信息数据
+        Data LabelTaggingInfo `json:"data"`
+    }
+)
+
+@server(
+    jwt: Auth
+    group: label_tagging
+    middleware: Authority
+)
+
+service Wechat {
+    // Create label tagging information | 创建LabelTagging信息
+    @handler createLabelTagging
+    post /label_tagging/create (LabelTaggingInfo) returns (BaseMsgResp)
+
+    // Update label tagging information | 更新LabelTagging信息
+    @handler updateLabelTagging
+    post /label_tagging/update (LabelTaggingInfo) returns (BaseMsgResp)
+
+    // Delete label tagging information | 删除LabelTagging信息
+    @handler deleteLabelTagging
+    post /label_tagging/delete (IDsReq) returns (BaseMsgResp)
+
+    // Get label tagging list | 获取LabelTagging信息列表
+    @handler getLabelTaggingList
+    post /label_tagging/list (LabelTaggingListReq) returns (LabelTaggingListResp)
+
+    // Get label tagging by ID | 通过ID获取LabelTagging信息
+    @handler getLabelTaggingById
+    post /label_tagging (IDReq) returns (LabelTaggingInfoResp)
+}

+ 8 - 0
desc/wechat/sop_stage.api

@@ -217,6 +217,10 @@ type (
         // 阶段名称
         Offset  *int `json:"offset,optional"`
     }
+    StageCopyReq {
+        // SopStage id | SopStage id
+        Id uint64 `json:"id"`
+    }
 )
 
 @server(
@@ -263,4 +267,8 @@ service Wechat {
     // Get sop stage move | 移动阶段顺序
     @handler moveSopStage
     post /sop_stage/move (SopStageMoveReq) returns (BaseMsgResp)
+
+    // stage copy | SopStage 复制
+    @handler sopStageCopy
+    post /sop_stage/copy (StageCopyReq) returns (BaseMsgResp)
 }

+ 28 - 0
desc/wechat/wx.api

@@ -129,6 +129,30 @@ type (
         Callback  *string `json:"callback,optional"`
     }
 
+    // Get wx list request params | Wx列表请求参数
+    WxSelectListReq {
+        // 租户id
+        OrganizationId  *uint64 `json:"organizationId,optional"`
+    }
+
+    // The response data of wx list | Wx列表数据
+    WxSelectListResp {
+        BaseDataInfo
+
+        // Wx list data | Wx列表数据
+        Data []WxSelectListInfo `json:"data"`
+    }
+
+    WxSelectListInfo {
+        BaseIDInfo
+
+        // 微信id
+        Wxid  *string `json:"wxid,optional"`
+
+        // 微信昵称
+        Nickname  *string `json:"nickname,optional"`
+    }
+
     // Wx information response | Wx信息返回体
     WxInfoResp {
         BaseDataInfo
@@ -201,6 +225,10 @@ service Wechat {
     @handler getWxList
     post /wx/list (WxListReq) returns (WxListResp)
 
+    // Get wx list | 获取Wx列表
+    @handler getSelectWxList
+    post /wx/selectList (WxSelectListReq) returns (WxSelectListResp)
+
     // Get wx allow and block list | 获取黑白名单列表
     @handler getWxAllowBlockList
     post /wx/getWxAllowBlockList (IDReq) returns (AllowBlockListResp)

+ 13 - 0
desc/wechat/xiaoice.api

@@ -14,6 +14,15 @@ type (
 
         Text *string `json:"text"`
     }
+
+    ChatReq {
+        // 大模型生成内容
+        AvatarId *string `json:"avatar_id"`
+
+        UserId *uint64 `json:"user_id"`
+
+        Text *string `json:"text"`
+    }
 )
 
 @server(
@@ -28,4 +37,8 @@ service Wechat {
     // gen gptbots | 调用gptbots
     @handler gptbotsMessage
     post /api/xiaoice/message (MessageReq) returns (BaseDataInfo)
+
+    // gen gptbots | message 接口的升级版,支持 avatar_id 参数
+    @handler gptbotsChat
+    post /api/xiaoice/chat (ChatReq) returns (BaseDataInfo)
 }

+ 149 - 8
ent/client.go

@@ -26,6 +26,7 @@ import (
 	"wechat-api/ent/employeeconfig"
 	"wechat-api/ent/label"
 	"wechat-api/ent/labelrelationship"
+	"wechat-api/ent/labeltagging"
 	"wechat-api/ent/message"
 	"wechat-api/ent/messagerecords"
 	"wechat-api/ent/msg"
@@ -92,6 +93,8 @@ type Client struct {
 	Label *LabelClient
 	// LabelRelationship is the client for interacting with the LabelRelationship builders.
 	LabelRelationship *LabelRelationshipClient
+	// LabelTagging is the client for interacting with the LabelTagging builders.
+	LabelTagging *LabelTaggingClient
 	// Message is the client for interacting with the Message builders.
 	Message *MessageClient
 	// MessageRecords is the client for interacting with the MessageRecords builders.
@@ -162,6 +165,7 @@ func (c *Client) init() {
 	c.EmployeeConfig = NewEmployeeConfigClient(c.config)
 	c.Label = NewLabelClient(c.config)
 	c.LabelRelationship = NewLabelRelationshipClient(c.config)
+	c.LabelTagging = NewLabelTaggingClient(c.config)
 	c.Message = NewMessageClient(c.config)
 	c.MessageRecords = NewMessageRecordsClient(c.config)
 	c.Msg = NewMsgClient(c.config)
@@ -291,6 +295,7 @@ func (c *Client) Tx(ctx context.Context) (*Tx, error) {
 		EmployeeConfig:      NewEmployeeConfigClient(cfg),
 		Label:               NewLabelClient(cfg),
 		LabelRelationship:   NewLabelRelationshipClient(cfg),
+		LabelTagging:        NewLabelTaggingClient(cfg),
 		Message:             NewMessageClient(cfg),
 		MessageRecords:      NewMessageRecordsClient(cfg),
 		Msg:                 NewMsgClient(cfg),
@@ -347,6 +352,7 @@ func (c *Client) BeginTx(ctx context.Context, opts *sql.TxOptions) (*Tx, error)
 		EmployeeConfig:      NewEmployeeConfigClient(cfg),
 		Label:               NewLabelClient(cfg),
 		LabelRelationship:   NewLabelRelationshipClient(cfg),
+		LabelTagging:        NewLabelTaggingClient(cfg),
 		Message:             NewMessageClient(cfg),
 		MessageRecords:      NewMessageRecordsClient(cfg),
 		Msg:                 NewMsgClient(cfg),
@@ -400,7 +406,7 @@ func (c *Client) Use(hooks ...Hook) {
 	for _, n := range []interface{ Use(...Hook) }{
 		c.Agent, c.AgentBase, c.AliyunAvatar, c.AllocAgent, c.BatchMsg, c.Category,
 		c.ChatRecords, c.ChatSession, c.Contact, c.CreditBalance, c.CreditUsage,
-		c.Employee, c.EmployeeConfig, c.Label, c.LabelRelationship, c.Message,
+		c.Employee, c.EmployeeConfig, c.Label, c.LabelRelationship, c.LabelTagging, c.Message,
 		c.MessageRecords, c.Msg, c.PayRecharge, c.Server, c.SopNode, c.SopStage,
 		c.SopTask, c.Token, c.Tutorial, c.UsageDetail, c.UsageStatisticDay,
 		c.UsageStatisticHour, c.UsageStatisticMonth, c.UsageTotal, c.WorkExperience,
@@ -416,7 +422,7 @@ func (c *Client) Intercept(interceptors ...Interceptor) {
 	for _, n := range []interface{ Intercept(...Interceptor) }{
 		c.Agent, c.AgentBase, c.AliyunAvatar, c.AllocAgent, c.BatchMsg, c.Category,
 		c.ChatRecords, c.ChatSession, c.Contact, c.CreditBalance, c.CreditUsage,
-		c.Employee, c.EmployeeConfig, c.Label, c.LabelRelationship, c.Message,
+		c.Employee, c.EmployeeConfig, c.Label, c.LabelRelationship, c.LabelTagging, c.Message,
 		c.MessageRecords, c.Msg, c.PayRecharge, c.Server, c.SopNode, c.SopStage,
 		c.SopTask, c.Token, c.Tutorial, c.UsageDetail, c.UsageStatisticDay,
 		c.UsageStatisticHour, c.UsageStatisticMonth, c.UsageTotal, c.WorkExperience,
@@ -459,6 +465,8 @@ func (c *Client) Mutate(ctx context.Context, m Mutation) (Value, error) {
 		return c.Label.mutate(ctx, m)
 	case *LabelRelationshipMutation:
 		return c.LabelRelationship.mutate(ctx, m)
+	case *LabelTaggingMutation:
+		return c.LabelTagging.mutate(ctx, m)
 	case *MessageMutation:
 		return c.Message.mutate(ctx, m)
 	case *MessageRecordsMutation:
@@ -2664,14 +2672,12 @@ func (c *LabelRelationshipClient) QueryLabels(lr *LabelRelationship) *LabelQuery
 
 // Hooks returns the client hooks.
 func (c *LabelRelationshipClient) Hooks() []Hook {
-	hooks := c.hooks.LabelRelationship
-	return append(hooks[:len(hooks):len(hooks)], labelrelationship.Hooks[:]...)
+	return c.hooks.LabelRelationship
 }
 
 // Interceptors returns the client interceptors.
 func (c *LabelRelationshipClient) Interceptors() []Interceptor {
-	inters := c.inters.LabelRelationship
-	return append(inters[:len(inters):len(inters)], labelrelationship.Interceptors[:]...)
+	return c.inters.LabelRelationship
 }
 
 func (c *LabelRelationshipClient) mutate(ctx context.Context, m *LabelRelationshipMutation) (Value, error) {
@@ -2689,6 +2695,141 @@ func (c *LabelRelationshipClient) mutate(ctx context.Context, m *LabelRelationsh
 	}
 }
 
+// LabelTaggingClient is a client for the LabelTagging schema.
+type LabelTaggingClient struct {
+	config
+}
+
+// NewLabelTaggingClient returns a client for the LabelTagging from the given config.
+func NewLabelTaggingClient(c config) *LabelTaggingClient {
+	return &LabelTaggingClient{config: c}
+}
+
+// Use adds a list of mutation hooks to the hooks stack.
+// A call to `Use(f, g, h)` equals to `labeltagging.Hooks(f(g(h())))`.
+func (c *LabelTaggingClient) Use(hooks ...Hook) {
+	c.hooks.LabelTagging = append(c.hooks.LabelTagging, hooks...)
+}
+
+// Intercept adds a list of query interceptors to the interceptors stack.
+// A call to `Intercept(f, g, h)` equals to `labeltagging.Intercept(f(g(h())))`.
+func (c *LabelTaggingClient) Intercept(interceptors ...Interceptor) {
+	c.inters.LabelTagging = append(c.inters.LabelTagging, interceptors...)
+}
+
+// Create returns a builder for creating a LabelTagging entity.
+func (c *LabelTaggingClient) Create() *LabelTaggingCreate {
+	mutation := newLabelTaggingMutation(c.config, OpCreate)
+	return &LabelTaggingCreate{config: c.config, hooks: c.Hooks(), mutation: mutation}
+}
+
+// CreateBulk returns a builder for creating a bulk of LabelTagging entities.
+func (c *LabelTaggingClient) CreateBulk(builders ...*LabelTaggingCreate) *LabelTaggingCreateBulk {
+	return &LabelTaggingCreateBulk{config: c.config, builders: builders}
+}
+
+// MapCreateBulk creates a bulk creation builder from the given slice. For each item in the slice, the function creates
+// a builder and applies setFunc on it.
+func (c *LabelTaggingClient) MapCreateBulk(slice any, setFunc func(*LabelTaggingCreate, int)) *LabelTaggingCreateBulk {
+	rv := reflect.ValueOf(slice)
+	if rv.Kind() != reflect.Slice {
+		return &LabelTaggingCreateBulk{err: fmt.Errorf("calling to LabelTaggingClient.MapCreateBulk with wrong type %T, need slice", slice)}
+	}
+	builders := make([]*LabelTaggingCreate, rv.Len())
+	for i := 0; i < rv.Len(); i++ {
+		builders[i] = c.Create()
+		setFunc(builders[i], i)
+	}
+	return &LabelTaggingCreateBulk{config: c.config, builders: builders}
+}
+
+// Update returns an update builder for LabelTagging.
+func (c *LabelTaggingClient) Update() *LabelTaggingUpdate {
+	mutation := newLabelTaggingMutation(c.config, OpUpdate)
+	return &LabelTaggingUpdate{config: c.config, hooks: c.Hooks(), mutation: mutation}
+}
+
+// UpdateOne returns an update builder for the given entity.
+func (c *LabelTaggingClient) UpdateOne(lt *LabelTagging) *LabelTaggingUpdateOne {
+	mutation := newLabelTaggingMutation(c.config, OpUpdateOne, withLabelTagging(lt))
+	return &LabelTaggingUpdateOne{config: c.config, hooks: c.Hooks(), mutation: mutation}
+}
+
+// UpdateOneID returns an update builder for the given id.
+func (c *LabelTaggingClient) UpdateOneID(id uint64) *LabelTaggingUpdateOne {
+	mutation := newLabelTaggingMutation(c.config, OpUpdateOne, withLabelTaggingID(id))
+	return &LabelTaggingUpdateOne{config: c.config, hooks: c.Hooks(), mutation: mutation}
+}
+
+// Delete returns a delete builder for LabelTagging.
+func (c *LabelTaggingClient) Delete() *LabelTaggingDelete {
+	mutation := newLabelTaggingMutation(c.config, OpDelete)
+	return &LabelTaggingDelete{config: c.config, hooks: c.Hooks(), mutation: mutation}
+}
+
+// DeleteOne returns a builder for deleting the given entity.
+func (c *LabelTaggingClient) DeleteOne(lt *LabelTagging) *LabelTaggingDeleteOne {
+	return c.DeleteOneID(lt.ID)
+}
+
+// DeleteOneID returns a builder for deleting the given entity by its id.
+func (c *LabelTaggingClient) DeleteOneID(id uint64) *LabelTaggingDeleteOne {
+	builder := c.Delete().Where(labeltagging.ID(id))
+	builder.mutation.id = &id
+	builder.mutation.op = OpDeleteOne
+	return &LabelTaggingDeleteOne{builder}
+}
+
+// Query returns a query builder for LabelTagging.
+func (c *LabelTaggingClient) Query() *LabelTaggingQuery {
+	return &LabelTaggingQuery{
+		config: c.config,
+		ctx:    &QueryContext{Type: TypeLabelTagging},
+		inters: c.Interceptors(),
+	}
+}
+
+// Get returns a LabelTagging entity by its id.
+func (c *LabelTaggingClient) Get(ctx context.Context, id uint64) (*LabelTagging, error) {
+	return c.Query().Where(labeltagging.ID(id)).Only(ctx)
+}
+
+// GetX is like Get, but panics if an error occurs.
+func (c *LabelTaggingClient) GetX(ctx context.Context, id uint64) *LabelTagging {
+	obj, err := c.Get(ctx, id)
+	if err != nil {
+		panic(err)
+	}
+	return obj
+}
+
+// Hooks returns the client hooks.
+func (c *LabelTaggingClient) Hooks() []Hook {
+	hooks := c.hooks.LabelTagging
+	return append(hooks[:len(hooks):len(hooks)], labeltagging.Hooks[:]...)
+}
+
+// Interceptors returns the client interceptors.
+func (c *LabelTaggingClient) Interceptors() []Interceptor {
+	inters := c.inters.LabelTagging
+	return append(inters[:len(inters):len(inters)], labeltagging.Interceptors[:]...)
+}
+
+func (c *LabelTaggingClient) mutate(ctx context.Context, m *LabelTaggingMutation) (Value, error) {
+	switch m.Op() {
+	case OpCreate:
+		return (&LabelTaggingCreate{config: c.config, hooks: c.Hooks(), mutation: m}).Save(ctx)
+	case OpUpdate:
+		return (&LabelTaggingUpdate{config: c.config, hooks: c.Hooks(), mutation: m}).Save(ctx)
+	case OpUpdateOne:
+		return (&LabelTaggingUpdateOne{config: c.config, hooks: c.Hooks(), mutation: m}).Save(ctx)
+	case OpDelete, OpDeleteOne:
+		return (&LabelTaggingDelete{config: c.config, hooks: c.Hooks(), mutation: m}).Exec(ctx)
+	default:
+		return nil, fmt.Errorf("ent: unknown LabelTagging mutation op: %q", m.Op())
+	}
+}
+
 // MessageClient is a client for the Message schema.
 type MessageClient struct {
 	config
@@ -5892,7 +6033,7 @@ type (
 	hooks struct {
 		Agent, AgentBase, AliyunAvatar, AllocAgent, BatchMsg, Category, ChatRecords,
 		ChatSession, Contact, CreditBalance, CreditUsage, Employee, EmployeeConfig,
-		Label, LabelRelationship, Message, MessageRecords, Msg, PayRecharge, Server,
+		Label, LabelRelationship, LabelTagging, Message, MessageRecords, Msg, PayRecharge, Server,
 		SopNode, SopStage, SopTask, Token, Tutorial, UsageDetail, UsageStatisticDay,
 		UsageStatisticHour, UsageStatisticMonth, UsageTotal, WorkExperience,
 		WpChatroom, WpChatroomMember, Wx, WxCard, WxCardUser, WxCardVisit []ent.Hook
@@ -5900,7 +6041,7 @@ type (
 	inters struct {
 		Agent, AgentBase, AliyunAvatar, AllocAgent, BatchMsg, Category, ChatRecords,
 		ChatSession, Contact, CreditBalance, CreditUsage, Employee, EmployeeConfig,
-		Label, LabelRelationship, Message, MessageRecords, Msg, PayRecharge, Server,
+		Label, LabelRelationship, LabelTagging, Message, MessageRecords, Msg, PayRecharge, Server,
 		SopNode, SopStage, SopTask, Token, Tutorial, UsageDetail, UsageStatisticDay,
 		UsageStatisticHour, UsageStatisticMonth, UsageTotal, WorkExperience,
 		WpChatroom, WpChatroomMember, Wx, WxCard, WxCardUser,

+ 2 - 0
ent/ent.go

@@ -23,6 +23,7 @@ import (
 	"wechat-api/ent/employeeconfig"
 	"wechat-api/ent/label"
 	"wechat-api/ent/labelrelationship"
+	"wechat-api/ent/labeltagging"
 	"wechat-api/ent/message"
 	"wechat-api/ent/messagerecords"
 	"wechat-api/ent/msg"
@@ -124,6 +125,7 @@ func checkColumn(table, column string) error {
 			employeeconfig.Table:      employeeconfig.ValidColumn,
 			label.Table:               label.ValidColumn,
 			labelrelationship.Table:   labelrelationship.ValidColumn,
+			labeltagging.Table:        labeltagging.ValidColumn,
 			message.Table:             message.ValidColumn,
 			messagerecords.Table:      messagerecords.ValidColumn,
 			msg.Table:                 msg.ValidColumn,

+ 12 - 0
ent/hook/hook.go

@@ -188,6 +188,18 @@ func (f LabelRelationshipFunc) Mutate(ctx context.Context, m ent.Mutation) (ent.
 	return nil, fmt.Errorf("unexpected mutation type %T. expect *ent.LabelRelationshipMutation", m)
 }
 
+// The LabelTaggingFunc type is an adapter to allow the use of ordinary
+// function as LabelTagging mutator.
+type LabelTaggingFunc func(context.Context, *ent.LabelTaggingMutation) (ent.Value, error)
+
+// Mutate calls f(ctx, m).
+func (f LabelTaggingFunc) Mutate(ctx context.Context, m ent.Mutation) (ent.Value, error) {
+	if mv, ok := m.(*ent.LabelTaggingMutation); ok {
+		return f(ctx, mv)
+	}
+	return nil, fmt.Errorf("unexpected mutation type %T. expect *ent.LabelTaggingMutation", m)
+}
+
 // The MessageFunc type is an adapter to allow the use of ordinary
 // function as Message mutator.
 type MessageFunc func(context.Context, *ent.MessageMutation) (ent.Value, error)

+ 30 - 0
ent/intercept/intercept.go

@@ -21,6 +21,7 @@ import (
 	"wechat-api/ent/employeeconfig"
 	"wechat-api/ent/label"
 	"wechat-api/ent/labelrelationship"
+	"wechat-api/ent/labeltagging"
 	"wechat-api/ent/message"
 	"wechat-api/ent/messagerecords"
 	"wechat-api/ent/msg"
@@ -509,6 +510,33 @@ func (f TraverseLabelRelationship) Traverse(ctx context.Context, q ent.Query) er
 	return fmt.Errorf("unexpected query type %T. expect *ent.LabelRelationshipQuery", q)
 }
 
+// The LabelTaggingFunc type is an adapter to allow the use of ordinary function as a Querier.
+type LabelTaggingFunc func(context.Context, *ent.LabelTaggingQuery) (ent.Value, error)
+
+// Query calls f(ctx, q).
+func (f LabelTaggingFunc) Query(ctx context.Context, q ent.Query) (ent.Value, error) {
+	if q, ok := q.(*ent.LabelTaggingQuery); ok {
+		return f(ctx, q)
+	}
+	return nil, fmt.Errorf("unexpected query type %T. expect *ent.LabelTaggingQuery", q)
+}
+
+// The TraverseLabelTagging type is an adapter to allow the use of ordinary function as Traverser.
+type TraverseLabelTagging func(context.Context, *ent.LabelTaggingQuery) error
+
+// Intercept is a dummy implementation of Intercept that returns the next Querier in the pipeline.
+func (f TraverseLabelTagging) Intercept(next ent.Querier) ent.Querier {
+	return next
+}
+
+// Traverse calls f(ctx, q).
+func (f TraverseLabelTagging) Traverse(ctx context.Context, q ent.Query) error {
+	if q, ok := q.(*ent.LabelTaggingQuery); ok {
+		return f(ctx, q)
+	}
+	return fmt.Errorf("unexpected query type %T. expect *ent.LabelTaggingQuery", q)
+}
+
 // The MessageFunc type is an adapter to allow the use of ordinary function as a Querier.
 type MessageFunc func(context.Context, *ent.MessageQuery) (ent.Value, error)
 
@@ -1136,6 +1164,8 @@ func NewQuery(q ent.Query) (Query, error) {
 		return &query[*ent.LabelQuery, predicate.Label, label.OrderOption]{typ: ent.TypeLabel, tq: q}, nil
 	case *ent.LabelRelationshipQuery:
 		return &query[*ent.LabelRelationshipQuery, predicate.LabelRelationship, labelrelationship.OrderOption]{typ: ent.TypeLabelRelationship, tq: q}, nil
+	case *ent.LabelTaggingQuery:
+		return &query[*ent.LabelTaggingQuery, predicate.LabelTagging, labeltagging.OrderOption]{typ: ent.TypeLabelTagging, tq: q}, nil
 	case *ent.MessageQuery:
 		return &query[*ent.MessageQuery, predicate.Message, message.OrderOption]{typ: ent.TypeMessage, tq: q}, nil
 	case *ent.MessageRecordsQuery:

+ 1 - 12
ent/labelrelationship.go

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

+ 0 - 16
ent/labelrelationship/labelrelationship.go

@@ -5,7 +5,6 @@ package labelrelationship
 import (
 	"time"
 
-	"entgo.io/ent"
 	"entgo.io/ent/dialect/sql"
 	"entgo.io/ent/dialect/sql/sqlgraph"
 )
@@ -21,8 +20,6 @@ const (
 	FieldUpdatedAt = "updated_at"
 	// FieldStatus holds the string denoting the status field in the database.
 	FieldStatus = "status"
-	// FieldDeletedAt holds the string denoting the deleted_at field in the database.
-	FieldDeletedAt = "deleted_at"
 	// FieldLabelID holds the string denoting the label_id field in the database.
 	FieldLabelID = "label_id"
 	// FieldContactID holds the string denoting the contact_id field in the database.
@@ -57,7 +54,6 @@ var Columns = []string{
 	FieldCreatedAt,
 	FieldUpdatedAt,
 	FieldStatus,
-	FieldDeletedAt,
 	FieldLabelID,
 	FieldContactID,
 	FieldOrganizationID,
@@ -73,14 +69,7 @@ func ValidColumn(column string) bool {
 	return false
 }
 
-// Note that the variables below are initialized by the runtime
-// package on the initialization of the application. Therefore,
-// it should be imported in the main as follows:
-//
-//	import _ "wechat-api/ent/runtime"
 var (
-	Hooks        [1]ent.Hook
-	Interceptors [1]ent.Interceptor
 	// DefaultCreatedAt holds the default value on creation for the "created_at" field.
 	DefaultCreatedAt func() time.Time
 	// DefaultUpdatedAt holds the default value on creation for the "updated_at" field.
@@ -120,11 +109,6 @@ func ByStatus(opts ...sql.OrderTermOption) OrderOption {
 	return sql.OrderByField(FieldStatus, opts...).ToFunc()
 }
 
-// ByDeletedAt orders the results by the deleted_at field.
-func ByDeletedAt(opts ...sql.OrderTermOption) OrderOption {
-	return sql.OrderByField(FieldDeletedAt, opts...).ToFunc()
-}
-
 // ByLabelID orders the results by the label_id field.
 func ByLabelID(opts ...sql.OrderTermOption) OrderOption {
 	return sql.OrderByField(FieldLabelID, opts...).ToFunc()

+ 0 - 55
ent/labelrelationship/where.go

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

+ 2 - 89
ent/labelrelationship_create.go

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

+ 4 - 68
ent/labelrelationship_update.go

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

+ 201 - 0
ent/labeltagging.go

@@ -0,0 +1,201 @@
+// Code generated by ent, DO NOT EDIT.
+
+package ent
+
+import (
+	"encoding/json"
+	"fmt"
+	"strings"
+	"time"
+	"wechat-api/ent/labeltagging"
+
+	"entgo.io/ent"
+	"entgo.io/ent/dialect/sql"
+)
+
+// LabelTagging is the model entity for the LabelTagging schema.
+type LabelTagging struct {
+	config `json:"-"`
+	// ID of the ent.
+	ID uint64 `json:"id,omitempty"`
+	// Create Time | 创建日期
+	CreatedAt time.Time `json:"created_at,omitempty"`
+	// Update Time | 修改日期
+	UpdatedAt time.Time `json:"updated_at,omitempty"`
+	// Status 1: normal 2: ban | 状态 1 正常 2 禁用
+	Status uint8 `json:"status,omitempty"`
+	// Delete Time | 删除日期
+	DeletedAt time.Time `json:"deleted_at,omitempty"`
+	// 机构 ID
+	OrganizationID uint64 `json:"organization_id,omitempty"`
+	// 标签类型:1好友,2群组,3公众号,4企业微信联系人
+	Type int `json:"type,omitempty"`
+	// 关键词
+	Conditions string `json:"conditions,omitempty"`
+	// 命中后需要打的标签
+	ActionLabelAdd []uint64 `json:"action_label_add,omitempty"`
+	// 命中后需要移除的标签
+	ActionLabelDel []uint64 `json:"action_label_del,omitempty"`
+	selectValues   sql.SelectValues
+}
+
+// scanValues returns the types for scanning values from sql.Rows.
+func (*LabelTagging) scanValues(columns []string) ([]any, error) {
+	values := make([]any, len(columns))
+	for i := range columns {
+		switch columns[i] {
+		case labeltagging.FieldActionLabelAdd, labeltagging.FieldActionLabelDel:
+			values[i] = new([]byte)
+		case labeltagging.FieldID, labeltagging.FieldStatus, labeltagging.FieldOrganizationID, labeltagging.FieldType:
+			values[i] = new(sql.NullInt64)
+		case labeltagging.FieldConditions:
+			values[i] = new(sql.NullString)
+		case labeltagging.FieldCreatedAt, labeltagging.FieldUpdatedAt, labeltagging.FieldDeletedAt:
+			values[i] = new(sql.NullTime)
+		default:
+			values[i] = new(sql.UnknownType)
+		}
+	}
+	return values, nil
+}
+
+// assignValues assigns the values that were returned from sql.Rows (after scanning)
+// to the LabelTagging fields.
+func (lt *LabelTagging) assignValues(columns []string, values []any) error {
+	if m, n := len(values), len(columns); m < n {
+		return fmt.Errorf("mismatch number of scan values: %d != %d", m, n)
+	}
+	for i := range columns {
+		switch columns[i] {
+		case labeltagging.FieldID:
+			value, ok := values[i].(*sql.NullInt64)
+			if !ok {
+				return fmt.Errorf("unexpected type %T for field id", value)
+			}
+			lt.ID = uint64(value.Int64)
+		case labeltagging.FieldCreatedAt:
+			if value, ok := values[i].(*sql.NullTime); !ok {
+				return fmt.Errorf("unexpected type %T for field created_at", values[i])
+			} else if value.Valid {
+				lt.CreatedAt = value.Time
+			}
+		case labeltagging.FieldUpdatedAt:
+			if value, ok := values[i].(*sql.NullTime); !ok {
+				return fmt.Errorf("unexpected type %T for field updated_at", values[i])
+			} else if value.Valid {
+				lt.UpdatedAt = value.Time
+			}
+		case labeltagging.FieldStatus:
+			if value, ok := values[i].(*sql.NullInt64); !ok {
+				return fmt.Errorf("unexpected type %T for field status", values[i])
+			} else if value.Valid {
+				lt.Status = uint8(value.Int64)
+			}
+		case labeltagging.FieldDeletedAt:
+			if value, ok := values[i].(*sql.NullTime); !ok {
+				return fmt.Errorf("unexpected type %T for field deleted_at", values[i])
+			} else if value.Valid {
+				lt.DeletedAt = value.Time
+			}
+		case labeltagging.FieldOrganizationID:
+			if value, ok := values[i].(*sql.NullInt64); !ok {
+				return fmt.Errorf("unexpected type %T for field organization_id", values[i])
+			} else if value.Valid {
+				lt.OrganizationID = uint64(value.Int64)
+			}
+		case labeltagging.FieldType:
+			if value, ok := values[i].(*sql.NullInt64); !ok {
+				return fmt.Errorf("unexpected type %T for field type", values[i])
+			} else if value.Valid {
+				lt.Type = int(value.Int64)
+			}
+		case labeltagging.FieldConditions:
+			if value, ok := values[i].(*sql.NullString); !ok {
+				return fmt.Errorf("unexpected type %T for field conditions", values[i])
+			} else if value.Valid {
+				lt.Conditions = value.String
+			}
+		case labeltagging.FieldActionLabelAdd:
+			if value, ok := values[i].(*[]byte); !ok {
+				return fmt.Errorf("unexpected type %T for field action_label_add", values[i])
+			} else if value != nil && len(*value) > 0 {
+				if err := json.Unmarshal(*value, &lt.ActionLabelAdd); err != nil {
+					return fmt.Errorf("unmarshal field action_label_add: %w", err)
+				}
+			}
+		case labeltagging.FieldActionLabelDel:
+			if value, ok := values[i].(*[]byte); !ok {
+				return fmt.Errorf("unexpected type %T for field action_label_del", values[i])
+			} else if value != nil && len(*value) > 0 {
+				if err := json.Unmarshal(*value, &lt.ActionLabelDel); err != nil {
+					return fmt.Errorf("unmarshal field action_label_del: %w", err)
+				}
+			}
+		default:
+			lt.selectValues.Set(columns[i], values[i])
+		}
+	}
+	return nil
+}
+
+// Value returns the ent.Value that was dynamically selected and assigned to the LabelTagging.
+// This includes values selected through modifiers, order, etc.
+func (lt *LabelTagging) Value(name string) (ent.Value, error) {
+	return lt.selectValues.Get(name)
+}
+
+// Update returns a builder for updating this LabelTagging.
+// Note that you need to call LabelTagging.Unwrap() before calling this method if this LabelTagging
+// was returned from a transaction, and the transaction was committed or rolled back.
+func (lt *LabelTagging) Update() *LabelTaggingUpdateOne {
+	return NewLabelTaggingClient(lt.config).UpdateOne(lt)
+}
+
+// Unwrap unwraps the LabelTagging entity that was returned from a transaction after it was closed,
+// so that all future queries will be executed through the driver which created the transaction.
+func (lt *LabelTagging) Unwrap() *LabelTagging {
+	_tx, ok := lt.config.driver.(*txDriver)
+	if !ok {
+		panic("ent: LabelTagging is not a transactional entity")
+	}
+	lt.config.driver = _tx.drv
+	return lt
+}
+
+// String implements the fmt.Stringer.
+func (lt *LabelTagging) String() string {
+	var builder strings.Builder
+	builder.WriteString("LabelTagging(")
+	builder.WriteString(fmt.Sprintf("id=%v, ", lt.ID))
+	builder.WriteString("created_at=")
+	builder.WriteString(lt.CreatedAt.Format(time.ANSIC))
+	builder.WriteString(", ")
+	builder.WriteString("updated_at=")
+	builder.WriteString(lt.UpdatedAt.Format(time.ANSIC))
+	builder.WriteString(", ")
+	builder.WriteString("status=")
+	builder.WriteString(fmt.Sprintf("%v", lt.Status))
+	builder.WriteString(", ")
+	builder.WriteString("deleted_at=")
+	builder.WriteString(lt.DeletedAt.Format(time.ANSIC))
+	builder.WriteString(", ")
+	builder.WriteString("organization_id=")
+	builder.WriteString(fmt.Sprintf("%v", lt.OrganizationID))
+	builder.WriteString(", ")
+	builder.WriteString("type=")
+	builder.WriteString(fmt.Sprintf("%v", lt.Type))
+	builder.WriteString(", ")
+	builder.WriteString("conditions=")
+	builder.WriteString(lt.Conditions)
+	builder.WriteString(", ")
+	builder.WriteString("action_label_add=")
+	builder.WriteString(fmt.Sprintf("%v", lt.ActionLabelAdd))
+	builder.WriteString(", ")
+	builder.WriteString("action_label_del=")
+	builder.WriteString(fmt.Sprintf("%v", lt.ActionLabelDel))
+	builder.WriteByte(')')
+	return builder.String()
+}
+
+// LabelTaggings is a parsable slice of LabelTagging.
+type LabelTaggings []*LabelTagging

+ 128 - 0
ent/labeltagging/labeltagging.go

@@ -0,0 +1,128 @@
+// Code generated by ent, DO NOT EDIT.
+
+package labeltagging
+
+import (
+	"time"
+
+	"entgo.io/ent"
+	"entgo.io/ent/dialect/sql"
+)
+
+const (
+	// Label holds the string label denoting the labeltagging type in the database.
+	Label = "label_tagging"
+	// FieldID holds the string denoting the id field in the database.
+	FieldID = "id"
+	// FieldCreatedAt holds the string denoting the created_at field in the database.
+	FieldCreatedAt = "created_at"
+	// FieldUpdatedAt holds the string denoting the updated_at field in the database.
+	FieldUpdatedAt = "updated_at"
+	// FieldStatus holds the string denoting the status field in the database.
+	FieldStatus = "status"
+	// FieldDeletedAt holds the string denoting the deleted_at field in the database.
+	FieldDeletedAt = "deleted_at"
+	// FieldOrganizationID holds the string denoting the organization_id field in the database.
+	FieldOrganizationID = "organization_id"
+	// FieldType holds the string denoting the type field in the database.
+	FieldType = "type"
+	// FieldConditions holds the string denoting the conditions field in the database.
+	FieldConditions = "conditions"
+	// FieldActionLabelAdd holds the string denoting the action_label_add field in the database.
+	FieldActionLabelAdd = "action_label_add"
+	// FieldActionLabelDel holds the string denoting the action_label_del field in the database.
+	FieldActionLabelDel = "action_label_del"
+	// Table holds the table name of the labeltagging in the database.
+	Table = "label_tagging"
+)
+
+// Columns holds all SQL columns for labeltagging fields.
+var Columns = []string{
+	FieldID,
+	FieldCreatedAt,
+	FieldUpdatedAt,
+	FieldStatus,
+	FieldDeletedAt,
+	FieldOrganizationID,
+	FieldType,
+	FieldConditions,
+	FieldActionLabelAdd,
+	FieldActionLabelDel,
+}
+
+// ValidColumn reports if the column name is valid (part of the table columns).
+func ValidColumn(column string) bool {
+	for i := range Columns {
+		if column == Columns[i] {
+			return true
+		}
+	}
+	return false
+}
+
+// Note that the variables below are initialized by the runtime
+// package on the initialization of the application. Therefore,
+// it should be imported in the main as follows:
+//
+//	import _ "wechat-api/ent/runtime"
+var (
+	Hooks        [1]ent.Hook
+	Interceptors [1]ent.Interceptor
+	// DefaultCreatedAt holds the default value on creation for the "created_at" field.
+	DefaultCreatedAt func() time.Time
+	// DefaultUpdatedAt holds the default value on creation for the "updated_at" field.
+	DefaultUpdatedAt func() time.Time
+	// UpdateDefaultUpdatedAt holds the default value on update for the "updated_at" field.
+	UpdateDefaultUpdatedAt func() time.Time
+	// DefaultStatus holds the default value on creation for the "status" field.
+	DefaultStatus uint8
+	// DefaultOrganizationID holds the default value on creation for the "organization_id" field.
+	DefaultOrganizationID uint64
+	// DefaultType holds the default value on creation for the "type" field.
+	DefaultType int
+	// DefaultConditions holds the default value on creation for the "conditions" field.
+	DefaultConditions string
+)
+
+// OrderOption defines the ordering options for the LabelTagging queries.
+type OrderOption func(*sql.Selector)
+
+// ByID orders the results by the id field.
+func ByID(opts ...sql.OrderTermOption) OrderOption {
+	return sql.OrderByField(FieldID, opts...).ToFunc()
+}
+
+// ByCreatedAt orders the results by the created_at field.
+func ByCreatedAt(opts ...sql.OrderTermOption) OrderOption {
+	return sql.OrderByField(FieldCreatedAt, opts...).ToFunc()
+}
+
+// ByUpdatedAt orders the results by the updated_at field.
+func ByUpdatedAt(opts ...sql.OrderTermOption) OrderOption {
+	return sql.OrderByField(FieldUpdatedAt, opts...).ToFunc()
+}
+
+// ByStatus orders the results by the status field.
+func ByStatus(opts ...sql.OrderTermOption) OrderOption {
+	return sql.OrderByField(FieldStatus, opts...).ToFunc()
+}
+
+// ByDeletedAt orders the results by the deleted_at field.
+func ByDeletedAt(opts ...sql.OrderTermOption) OrderOption {
+	return sql.OrderByField(FieldDeletedAt, opts...).ToFunc()
+}
+
+// ByOrganizationID orders the results by the organization_id field.
+func ByOrganizationID(opts ...sql.OrderTermOption) OrderOption {
+	return sql.OrderByField(FieldOrganizationID, opts...).ToFunc()
+}
+
+// ByType orders the results by the type field.
+func ByType(opts ...sql.OrderTermOption) OrderOption {
+	return sql.OrderByField(FieldType, opts...).ToFunc()
+}
+
+// ByConditions orders the results by the conditions field.
+func ByConditions(opts ...sql.OrderTermOption) OrderOption {
+	return sql.OrderByField(FieldConditions, opts...).ToFunc()
+}

+ 450 - 0
ent/labeltagging/where.go

@@ -0,0 +1,450 @@
+// Code generated by ent, DO NOT EDIT.
+
+package labeltagging
+
+import (
+	"time"
+	"wechat-api/ent/predicate"
+
+	"entgo.io/ent/dialect/sql"
+)
+
+// ID filters vertices based on their ID field.
+func ID(id uint64) predicate.LabelTagging {
+	return predicate.LabelTagging(sql.FieldEQ(FieldID, id))
+}
+
+// IDEQ applies the EQ predicate on the ID field.
+func IDEQ(id uint64) predicate.LabelTagging {
+	return predicate.LabelTagging(sql.FieldEQ(FieldID, id))
+}
+
+// IDNEQ applies the NEQ predicate on the ID field.
+func IDNEQ(id uint64) predicate.LabelTagging {
+	return predicate.LabelTagging(sql.FieldNEQ(FieldID, id))
+}
+
+// IDIn applies the In predicate on the ID field.
+func IDIn(ids ...uint64) predicate.LabelTagging {
+	return predicate.LabelTagging(sql.FieldIn(FieldID, ids...))
+}
+
+// IDNotIn applies the NotIn predicate on the ID field.
+func IDNotIn(ids ...uint64) predicate.LabelTagging {
+	return predicate.LabelTagging(sql.FieldNotIn(FieldID, ids...))
+}
+
+// IDGT applies the GT predicate on the ID field.
+func IDGT(id uint64) predicate.LabelTagging {
+	return predicate.LabelTagging(sql.FieldGT(FieldID, id))
+}
+
+// IDGTE applies the GTE predicate on the ID field.
+func IDGTE(id uint64) predicate.LabelTagging {
+	return predicate.LabelTagging(sql.FieldGTE(FieldID, id))
+}
+
+// IDLT applies the LT predicate on the ID field.
+func IDLT(id uint64) predicate.LabelTagging {
+	return predicate.LabelTagging(sql.FieldLT(FieldID, id))
+}
+
+// IDLTE applies the LTE predicate on the ID field.
+func IDLTE(id uint64) predicate.LabelTagging {
+	return predicate.LabelTagging(sql.FieldLTE(FieldID, id))
+}
+
+// CreatedAt applies equality check predicate on the "created_at" field. It's identical to CreatedAtEQ.
+func CreatedAt(v time.Time) predicate.LabelTagging {
+	return predicate.LabelTagging(sql.FieldEQ(FieldCreatedAt, v))
+}
+
+// UpdatedAt applies equality check predicate on the "updated_at" field. It's identical to UpdatedAtEQ.
+func UpdatedAt(v time.Time) predicate.LabelTagging {
+	return predicate.LabelTagging(sql.FieldEQ(FieldUpdatedAt, v))
+}
+
+// Status applies equality check predicate on the "status" field. It's identical to StatusEQ.
+func Status(v uint8) predicate.LabelTagging {
+	return predicate.LabelTagging(sql.FieldEQ(FieldStatus, v))
+}
+
+// DeletedAt applies equality check predicate on the "deleted_at" field. It's identical to DeletedAtEQ.
+func DeletedAt(v time.Time) predicate.LabelTagging {
+	return predicate.LabelTagging(sql.FieldEQ(FieldDeletedAt, v))
+}
+
+// OrganizationID applies equality check predicate on the "organization_id" field. It's identical to OrganizationIDEQ.
+func OrganizationID(v uint64) predicate.LabelTagging {
+	return predicate.LabelTagging(sql.FieldEQ(FieldOrganizationID, v))
+}
+
+// Type applies equality check predicate on the "type" field. It's identical to TypeEQ.
+func Type(v int) predicate.LabelTagging {
+	return predicate.LabelTagging(sql.FieldEQ(FieldType, v))
+}
+
+// Conditions applies equality check predicate on the "conditions" field. It's identical to ConditionsEQ.
+func Conditions(v string) predicate.LabelTagging {
+	return predicate.LabelTagging(sql.FieldEQ(FieldConditions, v))
+}
+
+// CreatedAtEQ applies the EQ predicate on the "created_at" field.
+func CreatedAtEQ(v time.Time) predicate.LabelTagging {
+	return predicate.LabelTagging(sql.FieldEQ(FieldCreatedAt, v))
+}
+
+// CreatedAtNEQ applies the NEQ predicate on the "created_at" field.
+func CreatedAtNEQ(v time.Time) predicate.LabelTagging {
+	return predicate.LabelTagging(sql.FieldNEQ(FieldCreatedAt, v))
+}
+
+// CreatedAtIn applies the In predicate on the "created_at" field.
+func CreatedAtIn(vs ...time.Time) predicate.LabelTagging {
+	return predicate.LabelTagging(sql.FieldIn(FieldCreatedAt, vs...))
+}
+
+// CreatedAtNotIn applies the NotIn predicate on the "created_at" field.
+func CreatedAtNotIn(vs ...time.Time) predicate.LabelTagging {
+	return predicate.LabelTagging(sql.FieldNotIn(FieldCreatedAt, vs...))
+}
+
+// CreatedAtGT applies the GT predicate on the "created_at" field.
+func CreatedAtGT(v time.Time) predicate.LabelTagging {
+	return predicate.LabelTagging(sql.FieldGT(FieldCreatedAt, v))
+}
+
+// CreatedAtGTE applies the GTE predicate on the "created_at" field.
+func CreatedAtGTE(v time.Time) predicate.LabelTagging {
+	return predicate.LabelTagging(sql.FieldGTE(FieldCreatedAt, v))
+}
+
+// CreatedAtLT applies the LT predicate on the "created_at" field.
+func CreatedAtLT(v time.Time) predicate.LabelTagging {
+	return predicate.LabelTagging(sql.FieldLT(FieldCreatedAt, v))
+}
+
+// CreatedAtLTE applies the LTE predicate on the "created_at" field.
+func CreatedAtLTE(v time.Time) predicate.LabelTagging {
+	return predicate.LabelTagging(sql.FieldLTE(FieldCreatedAt, v))
+}
+
+// UpdatedAtEQ applies the EQ predicate on the "updated_at" field.
+func UpdatedAtEQ(v time.Time) predicate.LabelTagging {
+	return predicate.LabelTagging(sql.FieldEQ(FieldUpdatedAt, v))
+}
+
+// UpdatedAtNEQ applies the NEQ predicate on the "updated_at" field.
+func UpdatedAtNEQ(v time.Time) predicate.LabelTagging {
+	return predicate.LabelTagging(sql.FieldNEQ(FieldUpdatedAt, v))
+}
+
+// UpdatedAtIn applies the In predicate on the "updated_at" field.
+func UpdatedAtIn(vs ...time.Time) predicate.LabelTagging {
+	return predicate.LabelTagging(sql.FieldIn(FieldUpdatedAt, vs...))
+}
+
+// UpdatedAtNotIn applies the NotIn predicate on the "updated_at" field.
+func UpdatedAtNotIn(vs ...time.Time) predicate.LabelTagging {
+	return predicate.LabelTagging(sql.FieldNotIn(FieldUpdatedAt, vs...))
+}
+
+// UpdatedAtGT applies the GT predicate on the "updated_at" field.
+func UpdatedAtGT(v time.Time) predicate.LabelTagging {
+	return predicate.LabelTagging(sql.FieldGT(FieldUpdatedAt, v))
+}
+
+// UpdatedAtGTE applies the GTE predicate on the "updated_at" field.
+func UpdatedAtGTE(v time.Time) predicate.LabelTagging {
+	return predicate.LabelTagging(sql.FieldGTE(FieldUpdatedAt, v))
+}
+
+// UpdatedAtLT applies the LT predicate on the "updated_at" field.
+func UpdatedAtLT(v time.Time) predicate.LabelTagging {
+	return predicate.LabelTagging(sql.FieldLT(FieldUpdatedAt, v))
+}
+
+// UpdatedAtLTE applies the LTE predicate on the "updated_at" field.
+func UpdatedAtLTE(v time.Time) predicate.LabelTagging {
+	return predicate.LabelTagging(sql.FieldLTE(FieldUpdatedAt, v))
+}
+
+// StatusEQ applies the EQ predicate on the "status" field.
+func StatusEQ(v uint8) predicate.LabelTagging {
+	return predicate.LabelTagging(sql.FieldEQ(FieldStatus, v))
+}
+
+// StatusNEQ applies the NEQ predicate on the "status" field.
+func StatusNEQ(v uint8) predicate.LabelTagging {
+	return predicate.LabelTagging(sql.FieldNEQ(FieldStatus, v))
+}
+
+// StatusIn applies the In predicate on the "status" field.
+func StatusIn(vs ...uint8) predicate.LabelTagging {
+	return predicate.LabelTagging(sql.FieldIn(FieldStatus, vs...))
+}
+
+// StatusNotIn applies the NotIn predicate on the "status" field.
+func StatusNotIn(vs ...uint8) predicate.LabelTagging {
+	return predicate.LabelTagging(sql.FieldNotIn(FieldStatus, vs...))
+}
+
+// StatusGT applies the GT predicate on the "status" field.
+func StatusGT(v uint8) predicate.LabelTagging {
+	return predicate.LabelTagging(sql.FieldGT(FieldStatus, v))
+}
+
+// StatusGTE applies the GTE predicate on the "status" field.
+func StatusGTE(v uint8) predicate.LabelTagging {
+	return predicate.LabelTagging(sql.FieldGTE(FieldStatus, v))
+}
+
+// StatusLT applies the LT predicate on the "status" field.
+func StatusLT(v uint8) predicate.LabelTagging {
+	return predicate.LabelTagging(sql.FieldLT(FieldStatus, v))
+}
+
+// StatusLTE applies the LTE predicate on the "status" field.
+func StatusLTE(v uint8) predicate.LabelTagging {
+	return predicate.LabelTagging(sql.FieldLTE(FieldStatus, v))
+}
+
+// StatusIsNil applies the IsNil predicate on the "status" field.
+func StatusIsNil() predicate.LabelTagging {
+	return predicate.LabelTagging(sql.FieldIsNull(FieldStatus))
+}
+
+// StatusNotNil applies the NotNil predicate on the "status" field.
+func StatusNotNil() predicate.LabelTagging {
+	return predicate.LabelTagging(sql.FieldNotNull(FieldStatus))
+}
+
+// DeletedAtEQ applies the EQ predicate on the "deleted_at" field.
+func DeletedAtEQ(v time.Time) predicate.LabelTagging {
+	return predicate.LabelTagging(sql.FieldEQ(FieldDeletedAt, v))
+}
+
+// DeletedAtNEQ applies the NEQ predicate on the "deleted_at" field.
+func DeletedAtNEQ(v time.Time) predicate.LabelTagging {
+	return predicate.LabelTagging(sql.FieldNEQ(FieldDeletedAt, v))
+}
+
+// DeletedAtIn applies the In predicate on the "deleted_at" field.
+func DeletedAtIn(vs ...time.Time) predicate.LabelTagging {
+	return predicate.LabelTagging(sql.FieldIn(FieldDeletedAt, vs...))
+}
+
+// DeletedAtNotIn applies the NotIn predicate on the "deleted_at" field.
+func DeletedAtNotIn(vs ...time.Time) predicate.LabelTagging {
+	return predicate.LabelTagging(sql.FieldNotIn(FieldDeletedAt, vs...))
+}
+
+// DeletedAtGT applies the GT predicate on the "deleted_at" field.
+func DeletedAtGT(v time.Time) predicate.LabelTagging {
+	return predicate.LabelTagging(sql.FieldGT(FieldDeletedAt, v))
+}
+
+// DeletedAtGTE applies the GTE predicate on the "deleted_at" field.
+func DeletedAtGTE(v time.Time) predicate.LabelTagging {
+	return predicate.LabelTagging(sql.FieldGTE(FieldDeletedAt, v))
+}
+
+// DeletedAtLT applies the LT predicate on the "deleted_at" field.
+func DeletedAtLT(v time.Time) predicate.LabelTagging {
+	return predicate.LabelTagging(sql.FieldLT(FieldDeletedAt, v))
+}
+
+// DeletedAtLTE applies the LTE predicate on the "deleted_at" field.
+func DeletedAtLTE(v time.Time) predicate.LabelTagging {
+	return predicate.LabelTagging(sql.FieldLTE(FieldDeletedAt, v))
+}
+
+// DeletedAtIsNil applies the IsNil predicate on the "deleted_at" field.
+func DeletedAtIsNil() predicate.LabelTagging {
+	return predicate.LabelTagging(sql.FieldIsNull(FieldDeletedAt))
+}
+
+// DeletedAtNotNil applies the NotNil predicate on the "deleted_at" field.
+func DeletedAtNotNil() predicate.LabelTagging {
+	return predicate.LabelTagging(sql.FieldNotNull(FieldDeletedAt))
+}
+
+// OrganizationIDEQ applies the EQ predicate on the "organization_id" field.
+func OrganizationIDEQ(v uint64) predicate.LabelTagging {
+	return predicate.LabelTagging(sql.FieldEQ(FieldOrganizationID, v))
+}
+
+// OrganizationIDNEQ applies the NEQ predicate on the "organization_id" field.
+func OrganizationIDNEQ(v uint64) predicate.LabelTagging {
+	return predicate.LabelTagging(sql.FieldNEQ(FieldOrganizationID, v))
+}
+
+// OrganizationIDIn applies the In predicate on the "organization_id" field.
+func OrganizationIDIn(vs ...uint64) predicate.LabelTagging {
+	return predicate.LabelTagging(sql.FieldIn(FieldOrganizationID, vs...))
+}
+
+// OrganizationIDNotIn applies the NotIn predicate on the "organization_id" field.
+func OrganizationIDNotIn(vs ...uint64) predicate.LabelTagging {
+	return predicate.LabelTagging(sql.FieldNotIn(FieldOrganizationID, vs...))
+}
+
+// OrganizationIDGT applies the GT predicate on the "organization_id" field.
+func OrganizationIDGT(v uint64) predicate.LabelTagging {
+	return predicate.LabelTagging(sql.FieldGT(FieldOrganizationID, v))
+}
+
+// OrganizationIDGTE applies the GTE predicate on the "organization_id" field.
+func OrganizationIDGTE(v uint64) predicate.LabelTagging {
+	return predicate.LabelTagging(sql.FieldGTE(FieldOrganizationID, v))
+}
+
+// OrganizationIDLT applies the LT predicate on the "organization_id" field.
+func OrganizationIDLT(v uint64) predicate.LabelTagging {
+	return predicate.LabelTagging(sql.FieldLT(FieldOrganizationID, v))
+}
+
+// OrganizationIDLTE applies the LTE predicate on the "organization_id" field.
+func OrganizationIDLTE(v uint64) predicate.LabelTagging {
+	return predicate.LabelTagging(sql.FieldLTE(FieldOrganizationID, v))
+}
+
+// TypeEQ applies the EQ predicate on the "type" field.
+func TypeEQ(v int) predicate.LabelTagging {
+	return predicate.LabelTagging(sql.FieldEQ(FieldType, v))
+}
+
+// TypeNEQ applies the NEQ predicate on the "type" field.
+func TypeNEQ(v int) predicate.LabelTagging {
+	return predicate.LabelTagging(sql.FieldNEQ(FieldType, v))
+}
+
+// TypeIn applies the In predicate on the "type" field.
+func TypeIn(vs ...int) predicate.LabelTagging {
+	return predicate.LabelTagging(sql.FieldIn(FieldType, vs...))
+}
+
+// TypeNotIn applies the NotIn predicate on the "type" field.
+func TypeNotIn(vs ...int) predicate.LabelTagging {
+	return predicate.LabelTagging(sql.FieldNotIn(FieldType, vs...))
+}
+
+// TypeGT applies the GT predicate on the "type" field.
+func TypeGT(v int) predicate.LabelTagging {
+	return predicate.LabelTagging(sql.FieldGT(FieldType, v))
+}
+
+// TypeGTE applies the GTE predicate on the "type" field.
+func TypeGTE(v int) predicate.LabelTagging {
+	return predicate.LabelTagging(sql.FieldGTE(FieldType, v))
+}
+
+// TypeLT applies the LT predicate on the "type" field.
+func TypeLT(v int) predicate.LabelTagging {
+	return predicate.LabelTagging(sql.FieldLT(FieldType, v))
+}
+
+// TypeLTE applies the LTE predicate on the "type" field.
+func TypeLTE(v int) predicate.LabelTagging {
+	return predicate.LabelTagging(sql.FieldLTE(FieldType, v))
+}
+
+// ConditionsEQ applies the EQ predicate on the "conditions" field.
+func ConditionsEQ(v string) predicate.LabelTagging {
+	return predicate.LabelTagging(sql.FieldEQ(FieldConditions, v))
+}
+
+// ConditionsNEQ applies the NEQ predicate on the "conditions" field.
+func ConditionsNEQ(v string) predicate.LabelTagging {
+	return predicate.LabelTagging(sql.FieldNEQ(FieldConditions, v))
+}
+
+// ConditionsIn applies the In predicate on the "conditions" field.
+func ConditionsIn(vs ...string) predicate.LabelTagging {
+	return predicate.LabelTagging(sql.FieldIn(FieldConditions, vs...))
+}
+
+// ConditionsNotIn applies the NotIn predicate on the "conditions" field.
+func ConditionsNotIn(vs ...string) predicate.LabelTagging {
+	return predicate.LabelTagging(sql.FieldNotIn(FieldConditions, vs...))
+}
+
+// ConditionsGT applies the GT predicate on the "conditions" field.
+func ConditionsGT(v string) predicate.LabelTagging {
+	return predicate.LabelTagging(sql.FieldGT(FieldConditions, v))
+}
+
+// ConditionsGTE applies the GTE predicate on the "conditions" field.
+func ConditionsGTE(v string) predicate.LabelTagging {
+	return predicate.LabelTagging(sql.FieldGTE(FieldConditions, v))
+}
+
+// ConditionsLT applies the LT predicate on the "conditions" field.
+func ConditionsLT(v string) predicate.LabelTagging {
+	return predicate.LabelTagging(sql.FieldLT(FieldConditions, v))
+}
+
+// ConditionsLTE applies the LTE predicate on the "conditions" field.
+func ConditionsLTE(v string) predicate.LabelTagging {
+	return predicate.LabelTagging(sql.FieldLTE(FieldConditions, v))
+}
+
+// ConditionsContains applies the Contains predicate on the "conditions" field.
+func ConditionsContains(v string) predicate.LabelTagging {
+	return predicate.LabelTagging(sql.FieldContains(FieldConditions, v))
+}
+
+// ConditionsHasPrefix applies the HasPrefix predicate on the "conditions" field.
+func ConditionsHasPrefix(v string) predicate.LabelTagging {
+	return predicate.LabelTagging(sql.FieldHasPrefix(FieldConditions, v))
+}
+
+// ConditionsHasSuffix applies the HasSuffix predicate on the "conditions" field.
+func ConditionsHasSuffix(v string) predicate.LabelTagging {
+	return predicate.LabelTagging(sql.FieldHasSuffix(FieldConditions, v))
+}
+
+// ConditionsEqualFold applies the EqualFold predicate on the "conditions" field.
+func ConditionsEqualFold(v string) predicate.LabelTagging {
+	return predicate.LabelTagging(sql.FieldEqualFold(FieldConditions, v))
+}
+
+// ConditionsContainsFold applies the ContainsFold predicate on the "conditions" field.
+func ConditionsContainsFold(v string) predicate.LabelTagging {
+	return predicate.LabelTagging(sql.FieldContainsFold(FieldConditions, v))
+}
+
+// ActionLabelAddIsNil applies the IsNil predicate on the "action_label_add" field.
+func ActionLabelAddIsNil() predicate.LabelTagging {
+	return predicate.LabelTagging(sql.FieldIsNull(FieldActionLabelAdd))
+}
+
+// ActionLabelAddNotNil applies the NotNil predicate on the "action_label_add" field.
+func ActionLabelAddNotNil() predicate.LabelTagging {
+	return predicate.LabelTagging(sql.FieldNotNull(FieldActionLabelAdd))
+}
+
+// ActionLabelDelIsNil applies the IsNil predicate on the "action_label_del" field.
+func ActionLabelDelIsNil() predicate.LabelTagging {
+	return predicate.LabelTagging(sql.FieldIsNull(FieldActionLabelDel))
+}
+
+// ActionLabelDelNotNil applies the NotNil predicate on the "action_label_del" field.
+func ActionLabelDelNotNil() predicate.LabelTagging {
+	return predicate.LabelTagging(sql.FieldNotNull(FieldActionLabelDel))
+}
+
+// And groups predicates with the AND operator between them.
+func And(predicates ...predicate.LabelTagging) predicate.LabelTagging {
+	return predicate.LabelTagging(sql.AndPredicates(predicates...))
+}
+
+// Or groups predicates with the OR operator between them.
+func Or(predicates ...predicate.LabelTagging) predicate.LabelTagging {
+	return predicate.LabelTagging(sql.OrPredicates(predicates...))
+}
+
+// Not applies the not operator on the given predicate.
+func Not(p predicate.LabelTagging) predicate.LabelTagging {
+	return predicate.LabelTagging(sql.NotPredicates(p))
+}

+ 1098 - 0
ent/labeltagging_create.go

@@ -0,0 +1,1098 @@
+// Code generated by ent, DO NOT EDIT.
+
+package ent
+
+import (
+	"context"
+	"errors"
+	"fmt"
+	"time"
+	"wechat-api/ent/labeltagging"
+
+	"entgo.io/ent/dialect/sql"
+	"entgo.io/ent/dialect/sql/sqlgraph"
+	"entgo.io/ent/schema/field"
+)
+
+// LabelTaggingCreate is the builder for creating a LabelTagging entity.
+type LabelTaggingCreate struct {
+	config
+	mutation *LabelTaggingMutation
+	hooks    []Hook
+	conflict []sql.ConflictOption
+}
+
+// SetCreatedAt sets the "created_at" field.
+func (ltc *LabelTaggingCreate) SetCreatedAt(t time.Time) *LabelTaggingCreate {
+	ltc.mutation.SetCreatedAt(t)
+	return ltc
+}
+
+// SetNillableCreatedAt sets the "created_at" field if the given value is not nil.
+func (ltc *LabelTaggingCreate) SetNillableCreatedAt(t *time.Time) *LabelTaggingCreate {
+	if t != nil {
+		ltc.SetCreatedAt(*t)
+	}
+	return ltc
+}
+
+// SetUpdatedAt sets the "updated_at" field.
+func (ltc *LabelTaggingCreate) SetUpdatedAt(t time.Time) *LabelTaggingCreate {
+	ltc.mutation.SetUpdatedAt(t)
+	return ltc
+}
+
+// SetNillableUpdatedAt sets the "updated_at" field if the given value is not nil.
+func (ltc *LabelTaggingCreate) SetNillableUpdatedAt(t *time.Time) *LabelTaggingCreate {
+	if t != nil {
+		ltc.SetUpdatedAt(*t)
+	}
+	return ltc
+}
+
+// SetStatus sets the "status" field.
+func (ltc *LabelTaggingCreate) SetStatus(u uint8) *LabelTaggingCreate {
+	ltc.mutation.SetStatus(u)
+	return ltc
+}
+
+// SetNillableStatus sets the "status" field if the given value is not nil.
+func (ltc *LabelTaggingCreate) SetNillableStatus(u *uint8) *LabelTaggingCreate {
+	if u != nil {
+		ltc.SetStatus(*u)
+	}
+	return ltc
+}
+
+// SetDeletedAt sets the "deleted_at" field.
+func (ltc *LabelTaggingCreate) SetDeletedAt(t time.Time) *LabelTaggingCreate {
+	ltc.mutation.SetDeletedAt(t)
+	return ltc
+}
+
+// SetNillableDeletedAt sets the "deleted_at" field if the given value is not nil.
+func (ltc *LabelTaggingCreate) SetNillableDeletedAt(t *time.Time) *LabelTaggingCreate {
+	if t != nil {
+		ltc.SetDeletedAt(*t)
+	}
+	return ltc
+}
+
+// SetOrganizationID sets the "organization_id" field.
+func (ltc *LabelTaggingCreate) SetOrganizationID(u uint64) *LabelTaggingCreate {
+	ltc.mutation.SetOrganizationID(u)
+	return ltc
+}
+
+// SetNillableOrganizationID sets the "organization_id" field if the given value is not nil.
+func (ltc *LabelTaggingCreate) SetNillableOrganizationID(u *uint64) *LabelTaggingCreate {
+	if u != nil {
+		ltc.SetOrganizationID(*u)
+	}
+	return ltc
+}
+
+// SetType sets the "type" field.
+func (ltc *LabelTaggingCreate) SetType(i int) *LabelTaggingCreate {
+	ltc.mutation.SetType(i)
+	return ltc
+}
+
+// SetNillableType sets the "type" field if the given value is not nil.
+func (ltc *LabelTaggingCreate) SetNillableType(i *int) *LabelTaggingCreate {
+	if i != nil {
+		ltc.SetType(*i)
+	}
+	return ltc
+}
+
+// SetConditions sets the "conditions" field.
+func (ltc *LabelTaggingCreate) SetConditions(s string) *LabelTaggingCreate {
+	ltc.mutation.SetConditions(s)
+	return ltc
+}
+
+// SetNillableConditions sets the "conditions" field if the given value is not nil.
+func (ltc *LabelTaggingCreate) SetNillableConditions(s *string) *LabelTaggingCreate {
+	if s != nil {
+		ltc.SetConditions(*s)
+	}
+	return ltc
+}
+
+// SetActionLabelAdd sets the "action_label_add" field.
+func (ltc *LabelTaggingCreate) SetActionLabelAdd(u []uint64) *LabelTaggingCreate {
+	ltc.mutation.SetActionLabelAdd(u)
+	return ltc
+}
+
+// SetActionLabelDel sets the "action_label_del" field.
+func (ltc *LabelTaggingCreate) SetActionLabelDel(u []uint64) *LabelTaggingCreate {
+	ltc.mutation.SetActionLabelDel(u)
+	return ltc
+}
+
+// SetID sets the "id" field.
+func (ltc *LabelTaggingCreate) SetID(u uint64) *LabelTaggingCreate {
+	ltc.mutation.SetID(u)
+	return ltc
+}
+
+// Mutation returns the LabelTaggingMutation object of the builder.
+func (ltc *LabelTaggingCreate) Mutation() *LabelTaggingMutation {
+	return ltc.mutation
+}
+
+// Save creates the LabelTagging in the database.
+func (ltc *LabelTaggingCreate) Save(ctx context.Context) (*LabelTagging, error) {
+	if err := ltc.defaults(); err != nil {
+		return nil, err
+	}
+	return withHooks(ctx, ltc.sqlSave, ltc.mutation, ltc.hooks)
+}
+
+// SaveX calls Save and panics if Save returns an error.
+func (ltc *LabelTaggingCreate) SaveX(ctx context.Context) *LabelTagging {
+	v, err := ltc.Save(ctx)
+	if err != nil {
+		panic(err)
+	}
+	return v
+}
+
+// Exec executes the query.
+func (ltc *LabelTaggingCreate) Exec(ctx context.Context) error {
+	_, err := ltc.Save(ctx)
+	return err
+}
+
+// ExecX is like Exec, but panics if an error occurs.
+func (ltc *LabelTaggingCreate) ExecX(ctx context.Context) {
+	if err := ltc.Exec(ctx); err != nil {
+		panic(err)
+	}
+}
+
+// defaults sets the default values of the builder before save.
+func (ltc *LabelTaggingCreate) defaults() error {
+	if _, ok := ltc.mutation.CreatedAt(); !ok {
+		if labeltagging.DefaultCreatedAt == nil {
+			return fmt.Errorf("ent: uninitialized labeltagging.DefaultCreatedAt (forgotten import ent/runtime?)")
+		}
+		v := labeltagging.DefaultCreatedAt()
+		ltc.mutation.SetCreatedAt(v)
+	}
+	if _, ok := ltc.mutation.UpdatedAt(); !ok {
+		if labeltagging.DefaultUpdatedAt == nil {
+			return fmt.Errorf("ent: uninitialized labeltagging.DefaultUpdatedAt (forgotten import ent/runtime?)")
+		}
+		v := labeltagging.DefaultUpdatedAt()
+		ltc.mutation.SetUpdatedAt(v)
+	}
+	if _, ok := ltc.mutation.Status(); !ok {
+		v := labeltagging.DefaultStatus
+		ltc.mutation.SetStatus(v)
+	}
+	if _, ok := ltc.mutation.OrganizationID(); !ok {
+		v := labeltagging.DefaultOrganizationID
+		ltc.mutation.SetOrganizationID(v)
+	}
+	if _, ok := ltc.mutation.GetType(); !ok {
+		v := labeltagging.DefaultType
+		ltc.mutation.SetType(v)
+	}
+	if _, ok := ltc.mutation.Conditions(); !ok {
+		v := labeltagging.DefaultConditions
+		ltc.mutation.SetConditions(v)
+	}
+	return nil
+}
+
+// check runs all checks and user-defined validators on the builder.
+func (ltc *LabelTaggingCreate) check() error {
+	if _, ok := ltc.mutation.CreatedAt(); !ok {
+		return &ValidationError{Name: "created_at", err: errors.New(`ent: missing required field "LabelTagging.created_at"`)}
+	}
+	if _, ok := ltc.mutation.UpdatedAt(); !ok {
+		return &ValidationError{Name: "updated_at", err: errors.New(`ent: missing required field "LabelTagging.updated_at"`)}
+	}
+	if _, ok := ltc.mutation.OrganizationID(); !ok {
+		return &ValidationError{Name: "organization_id", err: errors.New(`ent: missing required field "LabelTagging.organization_id"`)}
+	}
+	if _, ok := ltc.mutation.GetType(); !ok {
+		return &ValidationError{Name: "type", err: errors.New(`ent: missing required field "LabelTagging.type"`)}
+	}
+	if _, ok := ltc.mutation.Conditions(); !ok {
+		return &ValidationError{Name: "conditions", err: errors.New(`ent: missing required field "LabelTagging.conditions"`)}
+	}
+	return nil
+}
+
+func (ltc *LabelTaggingCreate) sqlSave(ctx context.Context) (*LabelTagging, error) {
+	if err := ltc.check(); err != nil {
+		return nil, err
+	}
+	_node, _spec := ltc.createSpec()
+	if err := sqlgraph.CreateNode(ctx, ltc.driver, _spec); err != nil {
+		if sqlgraph.IsConstraintError(err) {
+			err = &ConstraintError{msg: err.Error(), wrap: err}
+		}
+		return nil, err
+	}
+	if _spec.ID.Value != _node.ID {
+		id := _spec.ID.Value.(int64)
+		_node.ID = uint64(id)
+	}
+	ltc.mutation.id = &_node.ID
+	ltc.mutation.done = true
+	return _node, nil
+}
+
+func (ltc *LabelTaggingCreate) createSpec() (*LabelTagging, *sqlgraph.CreateSpec) {
+	var (
+		_node = &LabelTagging{config: ltc.config}
+		_spec = sqlgraph.NewCreateSpec(labeltagging.Table, sqlgraph.NewFieldSpec(labeltagging.FieldID, field.TypeUint64))
+	)
+	_spec.OnConflict = ltc.conflict
+	if id, ok := ltc.mutation.ID(); ok {
+		_node.ID = id
+		_spec.ID.Value = id
+	}
+	if value, ok := ltc.mutation.CreatedAt(); ok {
+		_spec.SetField(labeltagging.FieldCreatedAt, field.TypeTime, value)
+		_node.CreatedAt = value
+	}
+	if value, ok := ltc.mutation.UpdatedAt(); ok {
+		_spec.SetField(labeltagging.FieldUpdatedAt, field.TypeTime, value)
+		_node.UpdatedAt = value
+	}
+	if value, ok := ltc.mutation.Status(); ok {
+		_spec.SetField(labeltagging.FieldStatus, field.TypeUint8, value)
+		_node.Status = value
+	}
+	if value, ok := ltc.mutation.DeletedAt(); ok {
+		_spec.SetField(labeltagging.FieldDeletedAt, field.TypeTime, value)
+		_node.DeletedAt = value
+	}
+	if value, ok := ltc.mutation.OrganizationID(); ok {
+		_spec.SetField(labeltagging.FieldOrganizationID, field.TypeUint64, value)
+		_node.OrganizationID = value
+	}
+	if value, ok := ltc.mutation.GetType(); ok {
+		_spec.SetField(labeltagging.FieldType, field.TypeInt, value)
+		_node.Type = value
+	}
+	if value, ok := ltc.mutation.Conditions(); ok {
+		_spec.SetField(labeltagging.FieldConditions, field.TypeString, value)
+		_node.Conditions = value
+	}
+	if value, ok := ltc.mutation.ActionLabelAdd(); ok {
+		_spec.SetField(labeltagging.FieldActionLabelAdd, field.TypeJSON, value)
+		_node.ActionLabelAdd = value
+	}
+	if value, ok := ltc.mutation.ActionLabelDel(); ok {
+		_spec.SetField(labeltagging.FieldActionLabelDel, field.TypeJSON, value)
+		_node.ActionLabelDel = value
+	}
+	return _node, _spec
+}
+
+// OnConflict allows configuring the `ON CONFLICT` / `ON DUPLICATE KEY` clause
+// of the `INSERT` statement. For example:
+//
+//	client.LabelTagging.Create().
+//		SetCreatedAt(v).
+//		OnConflict(
+//			// Update the row with the new values
+//			// the was proposed for insertion.
+//			sql.ResolveWithNewValues(),
+//		).
+//		// Override some of the fields with custom
+//		// update values.
+//		Update(func(u *ent.LabelTaggingUpsert) {
+//			SetCreatedAt(v+v).
+//		}).
+//		Exec(ctx)
+func (ltc *LabelTaggingCreate) OnConflict(opts ...sql.ConflictOption) *LabelTaggingUpsertOne {
+	ltc.conflict = opts
+	return &LabelTaggingUpsertOne{
+		create: ltc,
+	}
+}
+
+// OnConflictColumns calls `OnConflict` and configures the columns
+// as conflict target. Using this option is equivalent to using:
+//
+//	client.LabelTagging.Create().
+//		OnConflict(sql.ConflictColumns(columns...)).
+//		Exec(ctx)
+func (ltc *LabelTaggingCreate) OnConflictColumns(columns ...string) *LabelTaggingUpsertOne {
+	ltc.conflict = append(ltc.conflict, sql.ConflictColumns(columns...))
+	return &LabelTaggingUpsertOne{
+		create: ltc,
+	}
+}
+
+type (
+	// LabelTaggingUpsertOne is the builder for "upsert"-ing
+	//  one LabelTagging node.
+	LabelTaggingUpsertOne struct {
+		create *LabelTaggingCreate
+	}
+
+	// LabelTaggingUpsert is the "OnConflict" setter.
+	LabelTaggingUpsert struct {
+		*sql.UpdateSet
+	}
+)
+
+// SetUpdatedAt sets the "updated_at" field.
+func (u *LabelTaggingUpsert) SetUpdatedAt(v time.Time) *LabelTaggingUpsert {
+	u.Set(labeltagging.FieldUpdatedAt, v)
+	return u
+}
+
+// UpdateUpdatedAt sets the "updated_at" field to the value that was provided on create.
+func (u *LabelTaggingUpsert) UpdateUpdatedAt() *LabelTaggingUpsert {
+	u.SetExcluded(labeltagging.FieldUpdatedAt)
+	return u
+}
+
+// SetStatus sets the "status" field.
+func (u *LabelTaggingUpsert) SetStatus(v uint8) *LabelTaggingUpsert {
+	u.Set(labeltagging.FieldStatus, v)
+	return u
+}
+
+// UpdateStatus sets the "status" field to the value that was provided on create.
+func (u *LabelTaggingUpsert) UpdateStatus() *LabelTaggingUpsert {
+	u.SetExcluded(labeltagging.FieldStatus)
+	return u
+}
+
+// AddStatus adds v to the "status" field.
+func (u *LabelTaggingUpsert) AddStatus(v uint8) *LabelTaggingUpsert {
+	u.Add(labeltagging.FieldStatus, v)
+	return u
+}
+
+// ClearStatus clears the value of the "status" field.
+func (u *LabelTaggingUpsert) ClearStatus() *LabelTaggingUpsert {
+	u.SetNull(labeltagging.FieldStatus)
+	return u
+}
+
+// SetDeletedAt sets the "deleted_at" field.
+func (u *LabelTaggingUpsert) SetDeletedAt(v time.Time) *LabelTaggingUpsert {
+	u.Set(labeltagging.FieldDeletedAt, v)
+	return u
+}
+
+// UpdateDeletedAt sets the "deleted_at" field to the value that was provided on create.
+func (u *LabelTaggingUpsert) UpdateDeletedAt() *LabelTaggingUpsert {
+	u.SetExcluded(labeltagging.FieldDeletedAt)
+	return u
+}
+
+// ClearDeletedAt clears the value of the "deleted_at" field.
+func (u *LabelTaggingUpsert) ClearDeletedAt() *LabelTaggingUpsert {
+	u.SetNull(labeltagging.FieldDeletedAt)
+	return u
+}
+
+// SetOrganizationID sets the "organization_id" field.
+func (u *LabelTaggingUpsert) SetOrganizationID(v uint64) *LabelTaggingUpsert {
+	u.Set(labeltagging.FieldOrganizationID, v)
+	return u
+}
+
+// UpdateOrganizationID sets the "organization_id" field to the value that was provided on create.
+func (u *LabelTaggingUpsert) UpdateOrganizationID() *LabelTaggingUpsert {
+	u.SetExcluded(labeltagging.FieldOrganizationID)
+	return u
+}
+
+// AddOrganizationID adds v to the "organization_id" field.
+func (u *LabelTaggingUpsert) AddOrganizationID(v uint64) *LabelTaggingUpsert {
+	u.Add(labeltagging.FieldOrganizationID, v)
+	return u
+}
+
+// SetType sets the "type" field.
+func (u *LabelTaggingUpsert) SetType(v int) *LabelTaggingUpsert {
+	u.Set(labeltagging.FieldType, v)
+	return u
+}
+
+// UpdateType sets the "type" field to the value that was provided on create.
+func (u *LabelTaggingUpsert) UpdateType() *LabelTaggingUpsert {
+	u.SetExcluded(labeltagging.FieldType)
+	return u
+}
+
+// AddType adds v to the "type" field.
+func (u *LabelTaggingUpsert) AddType(v int) *LabelTaggingUpsert {
+	u.Add(labeltagging.FieldType, v)
+	return u
+}
+
+// SetConditions sets the "conditions" field.
+func (u *LabelTaggingUpsert) SetConditions(v string) *LabelTaggingUpsert {
+	u.Set(labeltagging.FieldConditions, v)
+	return u
+}
+
+// UpdateConditions sets the "conditions" field to the value that was provided on create.
+func (u *LabelTaggingUpsert) UpdateConditions() *LabelTaggingUpsert {
+	u.SetExcluded(labeltagging.FieldConditions)
+	return u
+}
+
+// SetActionLabelAdd sets the "action_label_add" field.
+func (u *LabelTaggingUpsert) SetActionLabelAdd(v []uint64) *LabelTaggingUpsert {
+	u.Set(labeltagging.FieldActionLabelAdd, v)
+	return u
+}
+
+// UpdateActionLabelAdd sets the "action_label_add" field to the value that was provided on create.
+func (u *LabelTaggingUpsert) UpdateActionLabelAdd() *LabelTaggingUpsert {
+	u.SetExcluded(labeltagging.FieldActionLabelAdd)
+	return u
+}
+
+// ClearActionLabelAdd clears the value of the "action_label_add" field.
+func (u *LabelTaggingUpsert) ClearActionLabelAdd() *LabelTaggingUpsert {
+	u.SetNull(labeltagging.FieldActionLabelAdd)
+	return u
+}
+
+// SetActionLabelDel sets the "action_label_del" field.
+func (u *LabelTaggingUpsert) SetActionLabelDel(v []uint64) *LabelTaggingUpsert {
+	u.Set(labeltagging.FieldActionLabelDel, v)
+	return u
+}
+
+// UpdateActionLabelDel sets the "action_label_del" field to the value that was provided on create.
+func (u *LabelTaggingUpsert) UpdateActionLabelDel() *LabelTaggingUpsert {
+	u.SetExcluded(labeltagging.FieldActionLabelDel)
+	return u
+}
+
+// ClearActionLabelDel clears the value of the "action_label_del" field.
+func (u *LabelTaggingUpsert) ClearActionLabelDel() *LabelTaggingUpsert {
+	u.SetNull(labeltagging.FieldActionLabelDel)
+	return u
+}
+
+// UpdateNewValues updates the mutable fields using the new values that were set on create except the ID field.
+// Using this option is equivalent to using:
+//
+//	client.LabelTagging.Create().
+//		OnConflict(
+//			sql.ResolveWithNewValues(),
+//			sql.ResolveWith(func(u *sql.UpdateSet) {
+//				u.SetIgnore(labeltagging.FieldID)
+//			}),
+//		).
+//		Exec(ctx)
+func (u *LabelTaggingUpsertOne) UpdateNewValues() *LabelTaggingUpsertOne {
+	u.create.conflict = append(u.create.conflict, sql.ResolveWithNewValues())
+	u.create.conflict = append(u.create.conflict, sql.ResolveWith(func(s *sql.UpdateSet) {
+		if _, exists := u.create.mutation.ID(); exists {
+			s.SetIgnore(labeltagging.FieldID)
+		}
+		if _, exists := u.create.mutation.CreatedAt(); exists {
+			s.SetIgnore(labeltagging.FieldCreatedAt)
+		}
+	}))
+	return u
+}
+
+// Ignore sets each column to itself in case of conflict.
+// Using this option is equivalent to using:
+//
+//	client.LabelTagging.Create().
+//	    OnConflict(sql.ResolveWithIgnore()).
+//	    Exec(ctx)
+func (u *LabelTaggingUpsertOne) Ignore() *LabelTaggingUpsertOne {
+	u.create.conflict = append(u.create.conflict, sql.ResolveWithIgnore())
+	return u
+}
+
+// DoNothing configures the conflict_action to `DO NOTHING`.
+// Supported only by SQLite and PostgreSQL.
+func (u *LabelTaggingUpsertOne) DoNothing() *LabelTaggingUpsertOne {
+	u.create.conflict = append(u.create.conflict, sql.DoNothing())
+	return u
+}
+
+// Update allows overriding fields `UPDATE` values. See the LabelTaggingCreate.OnConflict
+// documentation for more info.
+func (u *LabelTaggingUpsertOne) Update(set func(*LabelTaggingUpsert)) *LabelTaggingUpsertOne {
+	u.create.conflict = append(u.create.conflict, sql.ResolveWith(func(update *sql.UpdateSet) {
+		set(&LabelTaggingUpsert{UpdateSet: update})
+	}))
+	return u
+}
+
+// SetUpdatedAt sets the "updated_at" field.
+func (u *LabelTaggingUpsertOne) SetUpdatedAt(v time.Time) *LabelTaggingUpsertOne {
+	return u.Update(func(s *LabelTaggingUpsert) {
+		s.SetUpdatedAt(v)
+	})
+}
+
+// UpdateUpdatedAt sets the "updated_at" field to the value that was provided on create.
+func (u *LabelTaggingUpsertOne) UpdateUpdatedAt() *LabelTaggingUpsertOne {
+	return u.Update(func(s *LabelTaggingUpsert) {
+		s.UpdateUpdatedAt()
+	})
+}
+
+// SetStatus sets the "status" field.
+func (u *LabelTaggingUpsertOne) SetStatus(v uint8) *LabelTaggingUpsertOne {
+	return u.Update(func(s *LabelTaggingUpsert) {
+		s.SetStatus(v)
+	})
+}
+
+// AddStatus adds v to the "status" field.
+func (u *LabelTaggingUpsertOne) AddStatus(v uint8) *LabelTaggingUpsertOne {
+	return u.Update(func(s *LabelTaggingUpsert) {
+		s.AddStatus(v)
+	})
+}
+
+// UpdateStatus sets the "status" field to the value that was provided on create.
+func (u *LabelTaggingUpsertOne) UpdateStatus() *LabelTaggingUpsertOne {
+	return u.Update(func(s *LabelTaggingUpsert) {
+		s.UpdateStatus()
+	})
+}
+
+// ClearStatus clears the value of the "status" field.
+func (u *LabelTaggingUpsertOne) ClearStatus() *LabelTaggingUpsertOne {
+	return u.Update(func(s *LabelTaggingUpsert) {
+		s.ClearStatus()
+	})
+}
+
+// SetDeletedAt sets the "deleted_at" field.
+func (u *LabelTaggingUpsertOne) SetDeletedAt(v time.Time) *LabelTaggingUpsertOne {
+	return u.Update(func(s *LabelTaggingUpsert) {
+		s.SetDeletedAt(v)
+	})
+}
+
+// UpdateDeletedAt sets the "deleted_at" field to the value that was provided on create.
+func (u *LabelTaggingUpsertOne) UpdateDeletedAt() *LabelTaggingUpsertOne {
+	return u.Update(func(s *LabelTaggingUpsert) {
+		s.UpdateDeletedAt()
+	})
+}
+
+// ClearDeletedAt clears the value of the "deleted_at" field.
+func (u *LabelTaggingUpsertOne) ClearDeletedAt() *LabelTaggingUpsertOne {
+	return u.Update(func(s *LabelTaggingUpsert) {
+		s.ClearDeletedAt()
+	})
+}
+
+// SetOrganizationID sets the "organization_id" field.
+func (u *LabelTaggingUpsertOne) SetOrganizationID(v uint64) *LabelTaggingUpsertOne {
+	return u.Update(func(s *LabelTaggingUpsert) {
+		s.SetOrganizationID(v)
+	})
+}
+
+// AddOrganizationID adds v to the "organization_id" field.
+func (u *LabelTaggingUpsertOne) AddOrganizationID(v uint64) *LabelTaggingUpsertOne {
+	return u.Update(func(s *LabelTaggingUpsert) {
+		s.AddOrganizationID(v)
+	})
+}
+
+// UpdateOrganizationID sets the "organization_id" field to the value that was provided on create.
+func (u *LabelTaggingUpsertOne) UpdateOrganizationID() *LabelTaggingUpsertOne {
+	return u.Update(func(s *LabelTaggingUpsert) {
+		s.UpdateOrganizationID()
+	})
+}
+
+// SetType sets the "type" field.
+func (u *LabelTaggingUpsertOne) SetType(v int) *LabelTaggingUpsertOne {
+	return u.Update(func(s *LabelTaggingUpsert) {
+		s.SetType(v)
+	})
+}
+
+// AddType adds v to the "type" field.
+func (u *LabelTaggingUpsertOne) AddType(v int) *LabelTaggingUpsertOne {
+	return u.Update(func(s *LabelTaggingUpsert) {
+		s.AddType(v)
+	})
+}
+
+// UpdateType sets the "type" field to the value that was provided on create.
+func (u *LabelTaggingUpsertOne) UpdateType() *LabelTaggingUpsertOne {
+	return u.Update(func(s *LabelTaggingUpsert) {
+		s.UpdateType()
+	})
+}
+
+// SetConditions sets the "conditions" field.
+func (u *LabelTaggingUpsertOne) SetConditions(v string) *LabelTaggingUpsertOne {
+	return u.Update(func(s *LabelTaggingUpsert) {
+		s.SetConditions(v)
+	})
+}
+
+// UpdateConditions sets the "conditions" field to the value that was provided on create.
+func (u *LabelTaggingUpsertOne) UpdateConditions() *LabelTaggingUpsertOne {
+	return u.Update(func(s *LabelTaggingUpsert) {
+		s.UpdateConditions()
+	})
+}
+
+// SetActionLabelAdd sets the "action_label_add" field.
+func (u *LabelTaggingUpsertOne) SetActionLabelAdd(v []uint64) *LabelTaggingUpsertOne {
+	return u.Update(func(s *LabelTaggingUpsert) {
+		s.SetActionLabelAdd(v)
+	})
+}
+
+// UpdateActionLabelAdd sets the "action_label_add" field to the value that was provided on create.
+func (u *LabelTaggingUpsertOne) UpdateActionLabelAdd() *LabelTaggingUpsertOne {
+	return u.Update(func(s *LabelTaggingUpsert) {
+		s.UpdateActionLabelAdd()
+	})
+}
+
+// ClearActionLabelAdd clears the value of the "action_label_add" field.
+func (u *LabelTaggingUpsertOne) ClearActionLabelAdd() *LabelTaggingUpsertOne {
+	return u.Update(func(s *LabelTaggingUpsert) {
+		s.ClearActionLabelAdd()
+	})
+}
+
+// SetActionLabelDel sets the "action_label_del" field.
+func (u *LabelTaggingUpsertOne) SetActionLabelDel(v []uint64) *LabelTaggingUpsertOne {
+	return u.Update(func(s *LabelTaggingUpsert) {
+		s.SetActionLabelDel(v)
+	})
+}
+
+// UpdateActionLabelDel sets the "action_label_del" field to the value that was provided on create.
+func (u *LabelTaggingUpsertOne) UpdateActionLabelDel() *LabelTaggingUpsertOne {
+	return u.Update(func(s *LabelTaggingUpsert) {
+		s.UpdateActionLabelDel()
+	})
+}
+
+// ClearActionLabelDel clears the value of the "action_label_del" field.
+func (u *LabelTaggingUpsertOne) ClearActionLabelDel() *LabelTaggingUpsertOne {
+	return u.Update(func(s *LabelTaggingUpsert) {
+		s.ClearActionLabelDel()
+	})
+}
+
+// Exec executes the query.
+func (u *LabelTaggingUpsertOne) Exec(ctx context.Context) error {
+	if len(u.create.conflict) == 0 {
+		return errors.New("ent: missing options for LabelTaggingCreate.OnConflict")
+	}
+	return u.create.Exec(ctx)
+}
+
+// ExecX is like Exec, but panics if an error occurs.
+func (u *LabelTaggingUpsertOne) ExecX(ctx context.Context) {
+	if err := u.create.Exec(ctx); err != nil {
+		panic(err)
+	}
+}
+
+// Exec executes the UPSERT query and returns the inserted/updated ID.
+func (u *LabelTaggingUpsertOne) ID(ctx context.Context) (id uint64, err error) {
+	node, err := u.create.Save(ctx)
+	if err != nil {
+		return id, err
+	}
+	return node.ID, nil
+}
+
+// IDX is like ID, but panics if an error occurs.
+func (u *LabelTaggingUpsertOne) IDX(ctx context.Context) uint64 {
+	id, err := u.ID(ctx)
+	if err != nil {
+		panic(err)
+	}
+	return id
+}
+
+// LabelTaggingCreateBulk is the builder for creating many LabelTagging entities in bulk.
+type LabelTaggingCreateBulk struct {
+	config
+	err      error
+	builders []*LabelTaggingCreate
+	conflict []sql.ConflictOption
+}
+
+// Save creates the LabelTagging entities in the database.
+func (ltcb *LabelTaggingCreateBulk) Save(ctx context.Context) ([]*LabelTagging, error) {
+	if ltcb.err != nil {
+		return nil, ltcb.err
+	}
+	specs := make([]*sqlgraph.CreateSpec, len(ltcb.builders))
+	nodes := make([]*LabelTagging, len(ltcb.builders))
+	mutators := make([]Mutator, len(ltcb.builders))
+	for i := range ltcb.builders {
+		func(i int, root context.Context) {
+			builder := ltcb.builders[i]
+			builder.defaults()
+			var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) {
+				mutation, ok := m.(*LabelTaggingMutation)
+				if !ok {
+					return nil, fmt.Errorf("unexpected mutation type %T", m)
+				}
+				if err := builder.check(); err != nil {
+					return nil, err
+				}
+				builder.mutation = mutation
+				var err error
+				nodes[i], specs[i] = builder.createSpec()
+				if i < len(mutators)-1 {
+					_, err = mutators[i+1].Mutate(root, ltcb.builders[i+1].mutation)
+				} else {
+					spec := &sqlgraph.BatchCreateSpec{Nodes: specs}
+					spec.OnConflict = ltcb.conflict
+					// Invoke the actual operation on the latest mutation in the chain.
+					if err = sqlgraph.BatchCreate(ctx, ltcb.driver, spec); err != nil {
+						if sqlgraph.IsConstraintError(err) {
+							err = &ConstraintError{msg: err.Error(), wrap: err}
+						}
+					}
+				}
+				if err != nil {
+					return nil, err
+				}
+				mutation.id = &nodes[i].ID
+				if specs[i].ID.Value != nil && nodes[i].ID == 0 {
+					id := specs[i].ID.Value.(int64)
+					nodes[i].ID = uint64(id)
+				}
+				mutation.done = true
+				return nodes[i], nil
+			})
+			for i := len(builder.hooks) - 1; i >= 0; i-- {
+				mut = builder.hooks[i](mut)
+			}
+			mutators[i] = mut
+		}(i, ctx)
+	}
+	if len(mutators) > 0 {
+		if _, err := mutators[0].Mutate(ctx, ltcb.builders[0].mutation); err != nil {
+			return nil, err
+		}
+	}
+	return nodes, nil
+}
+
+// SaveX is like Save, but panics if an error occurs.
+func (ltcb *LabelTaggingCreateBulk) SaveX(ctx context.Context) []*LabelTagging {
+	v, err := ltcb.Save(ctx)
+	if err != nil {
+		panic(err)
+	}
+	return v
+}
+
+// Exec executes the query.
+func (ltcb *LabelTaggingCreateBulk) Exec(ctx context.Context) error {
+	_, err := ltcb.Save(ctx)
+	return err
+}
+
+// ExecX is like Exec, but panics if an error occurs.
+func (ltcb *LabelTaggingCreateBulk) ExecX(ctx context.Context) {
+	if err := ltcb.Exec(ctx); err != nil {
+		panic(err)
+	}
+}
+
+// OnConflict allows configuring the `ON CONFLICT` / `ON DUPLICATE KEY` clause
+// of the `INSERT` statement. For example:
+//
+//	client.LabelTagging.CreateBulk(builders...).
+//		OnConflict(
+//			// Update the row with the new values
+//			// the was proposed for insertion.
+//			sql.ResolveWithNewValues(),
+//		).
+//		// Override some of the fields with custom
+//		// update values.
+//		Update(func(u *ent.LabelTaggingUpsert) {
+//			SetCreatedAt(v+v).
+//		}).
+//		Exec(ctx)
+func (ltcb *LabelTaggingCreateBulk) OnConflict(opts ...sql.ConflictOption) *LabelTaggingUpsertBulk {
+	ltcb.conflict = opts
+	return &LabelTaggingUpsertBulk{
+		create: ltcb,
+	}
+}
+
+// OnConflictColumns calls `OnConflict` and configures the columns
+// as conflict target. Using this option is equivalent to using:
+//
+//	client.LabelTagging.Create().
+//		OnConflict(sql.ConflictColumns(columns...)).
+//		Exec(ctx)
+func (ltcb *LabelTaggingCreateBulk) OnConflictColumns(columns ...string) *LabelTaggingUpsertBulk {
+	ltcb.conflict = append(ltcb.conflict, sql.ConflictColumns(columns...))
+	return &LabelTaggingUpsertBulk{
+		create: ltcb,
+	}
+}
+
+// LabelTaggingUpsertBulk is the builder for "upsert"-ing
+// a bulk of LabelTagging nodes.
+type LabelTaggingUpsertBulk struct {
+	create *LabelTaggingCreateBulk
+}
+
+// UpdateNewValues updates the mutable fields using the new values that
+// were set on create. Using this option is equivalent to using:
+//
+//	client.LabelTagging.Create().
+//		OnConflict(
+//			sql.ResolveWithNewValues(),
+//			sql.ResolveWith(func(u *sql.UpdateSet) {
+//				u.SetIgnore(labeltagging.FieldID)
+//			}),
+//		).
+//		Exec(ctx)
+func (u *LabelTaggingUpsertBulk) UpdateNewValues() *LabelTaggingUpsertBulk {
+	u.create.conflict = append(u.create.conflict, sql.ResolveWithNewValues())
+	u.create.conflict = append(u.create.conflict, sql.ResolveWith(func(s *sql.UpdateSet) {
+		for _, b := range u.create.builders {
+			if _, exists := b.mutation.ID(); exists {
+				s.SetIgnore(labeltagging.FieldID)
+			}
+			if _, exists := b.mutation.CreatedAt(); exists {
+				s.SetIgnore(labeltagging.FieldCreatedAt)
+			}
+		}
+	}))
+	return u
+}
+
+// Ignore sets each column to itself in case of conflict.
+// Using this option is equivalent to using:
+//
+//	client.LabelTagging.Create().
+//		OnConflict(sql.ResolveWithIgnore()).
+//		Exec(ctx)
+func (u *LabelTaggingUpsertBulk) Ignore() *LabelTaggingUpsertBulk {
+	u.create.conflict = append(u.create.conflict, sql.ResolveWithIgnore())
+	return u
+}
+
+// DoNothing configures the conflict_action to `DO NOTHING`.
+// Supported only by SQLite and PostgreSQL.
+func (u *LabelTaggingUpsertBulk) DoNothing() *LabelTaggingUpsertBulk {
+	u.create.conflict = append(u.create.conflict, sql.DoNothing())
+	return u
+}
+
+// Update allows overriding fields `UPDATE` values. See the LabelTaggingCreateBulk.OnConflict
+// documentation for more info.
+func (u *LabelTaggingUpsertBulk) Update(set func(*LabelTaggingUpsert)) *LabelTaggingUpsertBulk {
+	u.create.conflict = append(u.create.conflict, sql.ResolveWith(func(update *sql.UpdateSet) {
+		set(&LabelTaggingUpsert{UpdateSet: update})
+	}))
+	return u
+}
+
+// SetUpdatedAt sets the "updated_at" field.
+func (u *LabelTaggingUpsertBulk) SetUpdatedAt(v time.Time) *LabelTaggingUpsertBulk {
+	return u.Update(func(s *LabelTaggingUpsert) {
+		s.SetUpdatedAt(v)
+	})
+}
+
+// UpdateUpdatedAt sets the "updated_at" field to the value that was provided on create.
+func (u *LabelTaggingUpsertBulk) UpdateUpdatedAt() *LabelTaggingUpsertBulk {
+	return u.Update(func(s *LabelTaggingUpsert) {
+		s.UpdateUpdatedAt()
+	})
+}
+
+// SetStatus sets the "status" field.
+func (u *LabelTaggingUpsertBulk) SetStatus(v uint8) *LabelTaggingUpsertBulk {
+	return u.Update(func(s *LabelTaggingUpsert) {
+		s.SetStatus(v)
+	})
+}
+
+// AddStatus adds v to the "status" field.
+func (u *LabelTaggingUpsertBulk) AddStatus(v uint8) *LabelTaggingUpsertBulk {
+	return u.Update(func(s *LabelTaggingUpsert) {
+		s.AddStatus(v)
+	})
+}
+
+// UpdateStatus sets the "status" field to the value that was provided on create.
+func (u *LabelTaggingUpsertBulk) UpdateStatus() *LabelTaggingUpsertBulk {
+	return u.Update(func(s *LabelTaggingUpsert) {
+		s.UpdateStatus()
+	})
+}
+
+// ClearStatus clears the value of the "status" field.
+func (u *LabelTaggingUpsertBulk) ClearStatus() *LabelTaggingUpsertBulk {
+	return u.Update(func(s *LabelTaggingUpsert) {
+		s.ClearStatus()
+	})
+}
+
+// SetDeletedAt sets the "deleted_at" field.
+func (u *LabelTaggingUpsertBulk) SetDeletedAt(v time.Time) *LabelTaggingUpsertBulk {
+	return u.Update(func(s *LabelTaggingUpsert) {
+		s.SetDeletedAt(v)
+	})
+}
+
+// UpdateDeletedAt sets the "deleted_at" field to the value that was provided on create.
+func (u *LabelTaggingUpsertBulk) UpdateDeletedAt() *LabelTaggingUpsertBulk {
+	return u.Update(func(s *LabelTaggingUpsert) {
+		s.UpdateDeletedAt()
+	})
+}
+
+// ClearDeletedAt clears the value of the "deleted_at" field.
+func (u *LabelTaggingUpsertBulk) ClearDeletedAt() *LabelTaggingUpsertBulk {
+	return u.Update(func(s *LabelTaggingUpsert) {
+		s.ClearDeletedAt()
+	})
+}
+
+// SetOrganizationID sets the "organization_id" field.
+func (u *LabelTaggingUpsertBulk) SetOrganizationID(v uint64) *LabelTaggingUpsertBulk {
+	return u.Update(func(s *LabelTaggingUpsert) {
+		s.SetOrganizationID(v)
+	})
+}
+
+// AddOrganizationID adds v to the "organization_id" field.
+func (u *LabelTaggingUpsertBulk) AddOrganizationID(v uint64) *LabelTaggingUpsertBulk {
+	return u.Update(func(s *LabelTaggingUpsert) {
+		s.AddOrganizationID(v)
+	})
+}
+
+// UpdateOrganizationID sets the "organization_id" field to the value that was provided on create.
+func (u *LabelTaggingUpsertBulk) UpdateOrganizationID() *LabelTaggingUpsertBulk {
+	return u.Update(func(s *LabelTaggingUpsert) {
+		s.UpdateOrganizationID()
+	})
+}
+
+// SetType sets the "type" field.
+func (u *LabelTaggingUpsertBulk) SetType(v int) *LabelTaggingUpsertBulk {
+	return u.Update(func(s *LabelTaggingUpsert) {
+		s.SetType(v)
+	})
+}
+
+// AddType adds v to the "type" field.
+func (u *LabelTaggingUpsertBulk) AddType(v int) *LabelTaggingUpsertBulk {
+	return u.Update(func(s *LabelTaggingUpsert) {
+		s.AddType(v)
+	})
+}
+
+// UpdateType sets the "type" field to the value that was provided on create.
+func (u *LabelTaggingUpsertBulk) UpdateType() *LabelTaggingUpsertBulk {
+	return u.Update(func(s *LabelTaggingUpsert) {
+		s.UpdateType()
+	})
+}
+
+// SetConditions sets the "conditions" field.
+func (u *LabelTaggingUpsertBulk) SetConditions(v string) *LabelTaggingUpsertBulk {
+	return u.Update(func(s *LabelTaggingUpsert) {
+		s.SetConditions(v)
+	})
+}
+
+// UpdateConditions sets the "conditions" field to the value that was provided on create.
+func (u *LabelTaggingUpsertBulk) UpdateConditions() *LabelTaggingUpsertBulk {
+	return u.Update(func(s *LabelTaggingUpsert) {
+		s.UpdateConditions()
+	})
+}
+
+// SetActionLabelAdd sets the "action_label_add" field.
+func (u *LabelTaggingUpsertBulk) SetActionLabelAdd(v []uint64) *LabelTaggingUpsertBulk {
+	return u.Update(func(s *LabelTaggingUpsert) {
+		s.SetActionLabelAdd(v)
+	})
+}
+
+// UpdateActionLabelAdd sets the "action_label_add" field to the value that was provided on create.
+func (u *LabelTaggingUpsertBulk) UpdateActionLabelAdd() *LabelTaggingUpsertBulk {
+	return u.Update(func(s *LabelTaggingUpsert) {
+		s.UpdateActionLabelAdd()
+	})
+}
+
+// ClearActionLabelAdd clears the value of the "action_label_add" field.
+func (u *LabelTaggingUpsertBulk) ClearActionLabelAdd() *LabelTaggingUpsertBulk {
+	return u.Update(func(s *LabelTaggingUpsert) {
+		s.ClearActionLabelAdd()
+	})
+}
+
+// SetActionLabelDel sets the "action_label_del" field.
+func (u *LabelTaggingUpsertBulk) SetActionLabelDel(v []uint64) *LabelTaggingUpsertBulk {
+	return u.Update(func(s *LabelTaggingUpsert) {
+		s.SetActionLabelDel(v)
+	})
+}
+
+// UpdateActionLabelDel sets the "action_label_del" field to the value that was provided on create.
+func (u *LabelTaggingUpsertBulk) UpdateActionLabelDel() *LabelTaggingUpsertBulk {
+	return u.Update(func(s *LabelTaggingUpsert) {
+		s.UpdateActionLabelDel()
+	})
+}
+
+// ClearActionLabelDel clears the value of the "action_label_del" field.
+func (u *LabelTaggingUpsertBulk) ClearActionLabelDel() *LabelTaggingUpsertBulk {
+	return u.Update(func(s *LabelTaggingUpsert) {
+		s.ClearActionLabelDel()
+	})
+}
+
+// Exec executes the query.
+func (u *LabelTaggingUpsertBulk) Exec(ctx context.Context) error {
+	if u.create.err != nil {
+		return u.create.err
+	}
+	for i, b := range u.create.builders {
+		if len(b.conflict) != 0 {
+			return fmt.Errorf("ent: OnConflict was set for builder %d. Set it on the LabelTaggingCreateBulk instead", i)
+		}
+	}
+	if len(u.create.conflict) == 0 {
+		return errors.New("ent: missing options for LabelTaggingCreateBulk.OnConflict")
+	}
+	return u.create.Exec(ctx)
+}
+
+// ExecX is like Exec, but panics if an error occurs.
+func (u *LabelTaggingUpsertBulk) ExecX(ctx context.Context) {
+	if err := u.create.Exec(ctx); err != nil {
+		panic(err)
+	}
+}

+ 88 - 0
ent/labeltagging_delete.go

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

+ 526 - 0
ent/labeltagging_query.go

@@ -0,0 +1,526 @@
+// Code generated by ent, DO NOT EDIT.
+
+package ent
+
+import (
+	"context"
+	"fmt"
+	"math"
+	"wechat-api/ent/labeltagging"
+	"wechat-api/ent/predicate"
+
+	"entgo.io/ent/dialect/sql"
+	"entgo.io/ent/dialect/sql/sqlgraph"
+	"entgo.io/ent/schema/field"
+)
+
+// LabelTaggingQuery is the builder for querying LabelTagging entities.
+type LabelTaggingQuery struct {
+	config
+	ctx        *QueryContext
+	order      []labeltagging.OrderOption
+	inters     []Interceptor
+	predicates []predicate.LabelTagging
+	// intermediate query (i.e. traversal path).
+	sql  *sql.Selector
+	path func(context.Context) (*sql.Selector, error)
+}
+
+// Where adds a new predicate for the LabelTaggingQuery builder.
+func (ltq *LabelTaggingQuery) Where(ps ...predicate.LabelTagging) *LabelTaggingQuery {
+	ltq.predicates = append(ltq.predicates, ps...)
+	return ltq
+}
+
+// Limit the number of records to be returned by this query.
+func (ltq *LabelTaggingQuery) Limit(limit int) *LabelTaggingQuery {
+	ltq.ctx.Limit = &limit
+	return ltq
+}
+
+// Offset to start from.
+func (ltq *LabelTaggingQuery) Offset(offset int) *LabelTaggingQuery {
+	ltq.ctx.Offset = &offset
+	return ltq
+}
+
+// Unique configures the query builder to filter duplicate records on query.
+// By default, unique is set to true, and can be disabled using this method.
+func (ltq *LabelTaggingQuery) Unique(unique bool) *LabelTaggingQuery {
+	ltq.ctx.Unique = &unique
+	return ltq
+}
+
+// Order specifies how the records should be ordered.
+func (ltq *LabelTaggingQuery) Order(o ...labeltagging.OrderOption) *LabelTaggingQuery {
+	ltq.order = append(ltq.order, o...)
+	return ltq
+}
+
+// First returns the first LabelTagging entity from the query.
+// Returns a *NotFoundError when no LabelTagging was found.
+func (ltq *LabelTaggingQuery) First(ctx context.Context) (*LabelTagging, error) {
+	nodes, err := ltq.Limit(1).All(setContextOp(ctx, ltq.ctx, "First"))
+	if err != nil {
+		return nil, err
+	}
+	if len(nodes) == 0 {
+		return nil, &NotFoundError{labeltagging.Label}
+	}
+	return nodes[0], nil
+}
+
+// FirstX is like First, but panics if an error occurs.
+func (ltq *LabelTaggingQuery) FirstX(ctx context.Context) *LabelTagging {
+	node, err := ltq.First(ctx)
+	if err != nil && !IsNotFound(err) {
+		panic(err)
+	}
+	return node
+}
+
+// FirstID returns the first LabelTagging ID from the query.
+// Returns a *NotFoundError when no LabelTagging ID was found.
+func (ltq *LabelTaggingQuery) FirstID(ctx context.Context) (id uint64, err error) {
+	var ids []uint64
+	if ids, err = ltq.Limit(1).IDs(setContextOp(ctx, ltq.ctx, "FirstID")); err != nil {
+		return
+	}
+	if len(ids) == 0 {
+		err = &NotFoundError{labeltagging.Label}
+		return
+	}
+	return ids[0], nil
+}
+
+// FirstIDX is like FirstID, but panics if an error occurs.
+func (ltq *LabelTaggingQuery) FirstIDX(ctx context.Context) uint64 {
+	id, err := ltq.FirstID(ctx)
+	if err != nil && !IsNotFound(err) {
+		panic(err)
+	}
+	return id
+}
+
+// Only returns a single LabelTagging entity found by the query, ensuring it only returns one.
+// Returns a *NotSingularError when more than one LabelTagging entity is found.
+// Returns a *NotFoundError when no LabelTagging entities are found.
+func (ltq *LabelTaggingQuery) Only(ctx context.Context) (*LabelTagging, error) {
+	nodes, err := ltq.Limit(2).All(setContextOp(ctx, ltq.ctx, "Only"))
+	if err != nil {
+		return nil, err
+	}
+	switch len(nodes) {
+	case 1:
+		return nodes[0], nil
+	case 0:
+		return nil, &NotFoundError{labeltagging.Label}
+	default:
+		return nil, &NotSingularError{labeltagging.Label}
+	}
+}
+
+// OnlyX is like Only, but panics if an error occurs.
+func (ltq *LabelTaggingQuery) OnlyX(ctx context.Context) *LabelTagging {
+	node, err := ltq.Only(ctx)
+	if err != nil {
+		panic(err)
+	}
+	return node
+}
+
+// OnlyID is like Only, but returns the only LabelTagging ID in the query.
+// Returns a *NotSingularError when more than one LabelTagging ID is found.
+// Returns a *NotFoundError when no entities are found.
+func (ltq *LabelTaggingQuery) OnlyID(ctx context.Context) (id uint64, err error) {
+	var ids []uint64
+	if ids, err = ltq.Limit(2).IDs(setContextOp(ctx, ltq.ctx, "OnlyID")); err != nil {
+		return
+	}
+	switch len(ids) {
+	case 1:
+		id = ids[0]
+	case 0:
+		err = &NotFoundError{labeltagging.Label}
+	default:
+		err = &NotSingularError{labeltagging.Label}
+	}
+	return
+}
+
+// OnlyIDX is like OnlyID, but panics if an error occurs.
+func (ltq *LabelTaggingQuery) OnlyIDX(ctx context.Context) uint64 {
+	id, err := ltq.OnlyID(ctx)
+	if err != nil {
+		panic(err)
+	}
+	return id
+}
+
+// All executes the query and returns a list of LabelTaggings.
+func (ltq *LabelTaggingQuery) All(ctx context.Context) ([]*LabelTagging, error) {
+	ctx = setContextOp(ctx, ltq.ctx, "All")
+	if err := ltq.prepareQuery(ctx); err != nil {
+		return nil, err
+	}
+	qr := querierAll[[]*LabelTagging, *LabelTaggingQuery]()
+	return withInterceptors[[]*LabelTagging](ctx, ltq, qr, ltq.inters)
+}
+
+// AllX is like All, but panics if an error occurs.
+func (ltq *LabelTaggingQuery) AllX(ctx context.Context) []*LabelTagging {
+	nodes, err := ltq.All(ctx)
+	if err != nil {
+		panic(err)
+	}
+	return nodes
+}
+
+// IDs executes the query and returns a list of LabelTagging IDs.
+func (ltq *LabelTaggingQuery) IDs(ctx context.Context) (ids []uint64, err error) {
+	if ltq.ctx.Unique == nil && ltq.path != nil {
+		ltq.Unique(true)
+	}
+	ctx = setContextOp(ctx, ltq.ctx, "IDs")
+	if err = ltq.Select(labeltagging.FieldID).Scan(ctx, &ids); err != nil {
+		return nil, err
+	}
+	return ids, nil
+}
+
+// IDsX is like IDs, but panics if an error occurs.
+func (ltq *LabelTaggingQuery) IDsX(ctx context.Context) []uint64 {
+	ids, err := ltq.IDs(ctx)
+	if err != nil {
+		panic(err)
+	}
+	return ids
+}
+
+// Count returns the count of the given query.
+func (ltq *LabelTaggingQuery) Count(ctx context.Context) (int, error) {
+	ctx = setContextOp(ctx, ltq.ctx, "Count")
+	if err := ltq.prepareQuery(ctx); err != nil {
+		return 0, err
+	}
+	return withInterceptors[int](ctx, ltq, querierCount[*LabelTaggingQuery](), ltq.inters)
+}
+
+// CountX is like Count, but panics if an error occurs.
+func (ltq *LabelTaggingQuery) CountX(ctx context.Context) int {
+	count, err := ltq.Count(ctx)
+	if err != nil {
+		panic(err)
+	}
+	return count
+}
+
+// Exist returns true if the query has elements in the graph.
+func (ltq *LabelTaggingQuery) Exist(ctx context.Context) (bool, error) {
+	ctx = setContextOp(ctx, ltq.ctx, "Exist")
+	switch _, err := ltq.FirstID(ctx); {
+	case IsNotFound(err):
+		return false, nil
+	case err != nil:
+		return false, fmt.Errorf("ent: check existence: %w", err)
+	default:
+		return true, nil
+	}
+}
+
+// ExistX is like Exist, but panics if an error occurs.
+func (ltq *LabelTaggingQuery) ExistX(ctx context.Context) bool {
+	exist, err := ltq.Exist(ctx)
+	if err != nil {
+		panic(err)
+	}
+	return exist
+}
+
+// Clone returns a duplicate of the LabelTaggingQuery builder, including all associated steps. It can be
+// used to prepare common query builders and use them differently after the clone is made.
+func (ltq *LabelTaggingQuery) Clone() *LabelTaggingQuery {
+	if ltq == nil {
+		return nil
+	}
+	return &LabelTaggingQuery{
+		config:     ltq.config,
+		ctx:        ltq.ctx.Clone(),
+		order:      append([]labeltagging.OrderOption{}, ltq.order...),
+		inters:     append([]Interceptor{}, ltq.inters...),
+		predicates: append([]predicate.LabelTagging{}, ltq.predicates...),
+		// clone intermediate query.
+		sql:  ltq.sql.Clone(),
+		path: ltq.path,
+	}
+}
+
+// GroupBy is used to group vertices by one or more fields/columns.
+// It is often used with aggregate functions, like: count, max, mean, min, sum.
+//
+// Example:
+//
+//	var v []struct {
+//		CreatedAt time.Time `json:"created_at,omitempty"`
+//		Count int `json:"count,omitempty"`
+//	}
+//
+//	client.LabelTagging.Query().
+//		GroupBy(labeltagging.FieldCreatedAt).
+//		Aggregate(ent.Count()).
+//		Scan(ctx, &v)
+func (ltq *LabelTaggingQuery) GroupBy(field string, fields ...string) *LabelTaggingGroupBy {
+	ltq.ctx.Fields = append([]string{field}, fields...)
+	grbuild := &LabelTaggingGroupBy{build: ltq}
+	grbuild.flds = &ltq.ctx.Fields
+	grbuild.label = labeltagging.Label
+	grbuild.scan = grbuild.Scan
+	return grbuild
+}
+
+// Select allows the selection one or more fields/columns for the given query,
+// instead of selecting all fields in the entity.
+//
+// Example:
+//
+//	var v []struct {
+//		CreatedAt time.Time `json:"created_at,omitempty"`
+//	}
+//
+//	client.LabelTagging.Query().
+//		Select(labeltagging.FieldCreatedAt).
+//		Scan(ctx, &v)
+func (ltq *LabelTaggingQuery) Select(fields ...string) *LabelTaggingSelect {
+	ltq.ctx.Fields = append(ltq.ctx.Fields, fields...)
+	sbuild := &LabelTaggingSelect{LabelTaggingQuery: ltq}
+	sbuild.label = labeltagging.Label
+	sbuild.flds, sbuild.scan = &ltq.ctx.Fields, sbuild.Scan
+	return sbuild
+}
+
+// Aggregate returns a LabelTaggingSelect configured with the given aggregations.
+func (ltq *LabelTaggingQuery) Aggregate(fns ...AggregateFunc) *LabelTaggingSelect {
+	return ltq.Select().Aggregate(fns...)
+}
+
+func (ltq *LabelTaggingQuery) prepareQuery(ctx context.Context) error {
+	for _, inter := range ltq.inters {
+		if inter == nil {
+			return fmt.Errorf("ent: uninitialized interceptor (forgotten import ent/runtime?)")
+		}
+		if trv, ok := inter.(Traverser); ok {
+			if err := trv.Traverse(ctx, ltq); err != nil {
+				return err
+			}
+		}
+	}
+	for _, f := range ltq.ctx.Fields {
+		if !labeltagging.ValidColumn(f) {
+			return &ValidationError{Name: f, err: fmt.Errorf("ent: invalid field %q for query", f)}
+		}
+	}
+	if ltq.path != nil {
+		prev, err := ltq.path(ctx)
+		if err != nil {
+			return err
+		}
+		ltq.sql = prev
+	}
+	return nil
+}
+
+func (ltq *LabelTaggingQuery) sqlAll(ctx context.Context, hooks ...queryHook) ([]*LabelTagging, error) {
+	var (
+		nodes = []*LabelTagging{}
+		_spec = ltq.querySpec()
+	)
+	_spec.ScanValues = func(columns []string) ([]any, error) {
+		return (*LabelTagging).scanValues(nil, columns)
+	}
+	_spec.Assign = func(columns []string, values []any) error {
+		node := &LabelTagging{config: ltq.config}
+		nodes = append(nodes, node)
+		return node.assignValues(columns, values)
+	}
+	for i := range hooks {
+		hooks[i](ctx, _spec)
+	}
+	if err := sqlgraph.QueryNodes(ctx, ltq.driver, _spec); err != nil {
+		return nil, err
+	}
+	if len(nodes) == 0 {
+		return nodes, nil
+	}
+	return nodes, nil
+}
+
+func (ltq *LabelTaggingQuery) sqlCount(ctx context.Context) (int, error) {
+	_spec := ltq.querySpec()
+	_spec.Node.Columns = ltq.ctx.Fields
+	if len(ltq.ctx.Fields) > 0 {
+		_spec.Unique = ltq.ctx.Unique != nil && *ltq.ctx.Unique
+	}
+	return sqlgraph.CountNodes(ctx, ltq.driver, _spec)
+}
+
+func (ltq *LabelTaggingQuery) querySpec() *sqlgraph.QuerySpec {
+	_spec := sqlgraph.NewQuerySpec(labeltagging.Table, labeltagging.Columns, sqlgraph.NewFieldSpec(labeltagging.FieldID, field.TypeUint64))
+	_spec.From = ltq.sql
+	if unique := ltq.ctx.Unique; unique != nil {
+		_spec.Unique = *unique
+	} else if ltq.path != nil {
+		_spec.Unique = true
+	}
+	if fields := ltq.ctx.Fields; len(fields) > 0 {
+		_spec.Node.Columns = make([]string, 0, len(fields))
+		_spec.Node.Columns = append(_spec.Node.Columns, labeltagging.FieldID)
+		for i := range fields {
+			if fields[i] != labeltagging.FieldID {
+				_spec.Node.Columns = append(_spec.Node.Columns, fields[i])
+			}
+		}
+	}
+	if ps := ltq.predicates; len(ps) > 0 {
+		_spec.Predicate = func(selector *sql.Selector) {
+			for i := range ps {
+				ps[i](selector)
+			}
+		}
+	}
+	if limit := ltq.ctx.Limit; limit != nil {
+		_spec.Limit = *limit
+	}
+	if offset := ltq.ctx.Offset; offset != nil {
+		_spec.Offset = *offset
+	}
+	if ps := ltq.order; len(ps) > 0 {
+		_spec.Order = func(selector *sql.Selector) {
+			for i := range ps {
+				ps[i](selector)
+			}
+		}
+	}
+	return _spec
+}
+
+func (ltq *LabelTaggingQuery) sqlQuery(ctx context.Context) *sql.Selector {
+	builder := sql.Dialect(ltq.driver.Dialect())
+	t1 := builder.Table(labeltagging.Table)
+	columns := ltq.ctx.Fields
+	if len(columns) == 0 {
+		columns = labeltagging.Columns
+	}
+	selector := builder.Select(t1.Columns(columns...)...).From(t1)
+	if ltq.sql != nil {
+		selector = ltq.sql
+		selector.Select(selector.Columns(columns...)...)
+	}
+	if ltq.ctx.Unique != nil && *ltq.ctx.Unique {
+		selector.Distinct()
+	}
+	for _, p := range ltq.predicates {
+		p(selector)
+	}
+	for _, p := range ltq.order {
+		p(selector)
+	}
+	if offset := ltq.ctx.Offset; offset != nil {
+		// limit is mandatory for offset clause. We start
+		// with default value, and override it below if needed.
+		selector.Offset(*offset).Limit(math.MaxInt32)
+	}
+	if limit := ltq.ctx.Limit; limit != nil {
+		selector.Limit(*limit)
+	}
+	return selector
+}
+
+// LabelTaggingGroupBy is the group-by builder for LabelTagging entities.
+type LabelTaggingGroupBy struct {
+	selector
+	build *LabelTaggingQuery
+}
+
+// Aggregate adds the given aggregation functions to the group-by query.
+func (ltgb *LabelTaggingGroupBy) Aggregate(fns ...AggregateFunc) *LabelTaggingGroupBy {
+	ltgb.fns = append(ltgb.fns, fns...)
+	return ltgb
+}
+
+// Scan applies the selector query and scans the result into the given value.
+func (ltgb *LabelTaggingGroupBy) Scan(ctx context.Context, v any) error {
+	ctx = setContextOp(ctx, ltgb.build.ctx, "GroupBy")
+	if err := ltgb.build.prepareQuery(ctx); err != nil {
+		return err
+	}
+	return scanWithInterceptors[*LabelTaggingQuery, *LabelTaggingGroupBy](ctx, ltgb.build, ltgb, ltgb.build.inters, v)
+}
+
+func (ltgb *LabelTaggingGroupBy) sqlScan(ctx context.Context, root *LabelTaggingQuery, v any) error {
+	selector := root.sqlQuery(ctx).Select()
+	aggregation := make([]string, 0, len(ltgb.fns))
+	for _, fn := range ltgb.fns {
+		aggregation = append(aggregation, fn(selector))
+	}
+	if len(selector.SelectedColumns()) == 0 {
+		columns := make([]string, 0, len(*ltgb.flds)+len(ltgb.fns))
+		for _, f := range *ltgb.flds {
+			columns = append(columns, selector.C(f))
+		}
+		columns = append(columns, aggregation...)
+		selector.Select(columns...)
+	}
+	selector.GroupBy(selector.Columns(*ltgb.flds...)...)
+	if err := selector.Err(); err != nil {
+		return err
+	}
+	rows := &sql.Rows{}
+	query, args := selector.Query()
+	if err := ltgb.build.driver.Query(ctx, query, args, rows); err != nil {
+		return err
+	}
+	defer rows.Close()
+	return sql.ScanSlice(rows, v)
+}
+
+// LabelTaggingSelect is the builder for selecting fields of LabelTagging entities.
+type LabelTaggingSelect struct {
+	*LabelTaggingQuery
+	selector
+}
+
+// Aggregate adds the given aggregation functions to the selector query.
+func (lts *LabelTaggingSelect) Aggregate(fns ...AggregateFunc) *LabelTaggingSelect {
+	lts.fns = append(lts.fns, fns...)
+	return lts
+}
+
+// Scan applies the selector query and scans the result into the given value.
+func (lts *LabelTaggingSelect) Scan(ctx context.Context, v any) error {
+	ctx = setContextOp(ctx, lts.ctx, "Select")
+	if err := lts.prepareQuery(ctx); err != nil {
+		return err
+	}
+	return scanWithInterceptors[*LabelTaggingQuery, *LabelTaggingSelect](ctx, lts.LabelTaggingQuery, lts, lts.inters, v)
+}
+
+func (lts *LabelTaggingSelect) sqlScan(ctx context.Context, root *LabelTaggingQuery, v any) error {
+	selector := root.sqlQuery(ctx)
+	aggregation := make([]string, 0, len(lts.fns))
+	for _, fn := range lts.fns {
+		aggregation = append(aggregation, fn(selector))
+	}
+	switch n := len(*lts.selector.flds); {
+	case n == 0 && len(aggregation) > 0:
+		selector.Select(aggregation...)
+	case n != 0 && len(aggregation) > 0:
+		selector.AppendSelect(aggregation...)
+	}
+	rows := &sql.Rows{}
+	query, args := selector.Query()
+	if err := lts.driver.Query(ctx, query, args, rows); err != nil {
+		return err
+	}
+	defer rows.Close()
+	return sql.ScanSlice(rows, v)
+}

+ 607 - 0
ent/labeltagging_update.go

@@ -0,0 +1,607 @@
+// Code generated by ent, DO NOT EDIT.
+
+package ent
+
+import (
+	"context"
+	"errors"
+	"fmt"
+	"time"
+	"wechat-api/ent/labeltagging"
+	"wechat-api/ent/predicate"
+
+	"entgo.io/ent/dialect/sql"
+	"entgo.io/ent/dialect/sql/sqlgraph"
+	"entgo.io/ent/dialect/sql/sqljson"
+	"entgo.io/ent/schema/field"
+)
+
+// LabelTaggingUpdate is the builder for updating LabelTagging entities.
+type LabelTaggingUpdate struct {
+	config
+	hooks    []Hook
+	mutation *LabelTaggingMutation
+}
+
+// Where appends a list predicates to the LabelTaggingUpdate builder.
+func (ltu *LabelTaggingUpdate) Where(ps ...predicate.LabelTagging) *LabelTaggingUpdate {
+	ltu.mutation.Where(ps...)
+	return ltu
+}
+
+// SetUpdatedAt sets the "updated_at" field.
+func (ltu *LabelTaggingUpdate) SetUpdatedAt(t time.Time) *LabelTaggingUpdate {
+	ltu.mutation.SetUpdatedAt(t)
+	return ltu
+}
+
+// SetStatus sets the "status" field.
+func (ltu *LabelTaggingUpdate) SetStatus(u uint8) *LabelTaggingUpdate {
+	ltu.mutation.ResetStatus()
+	ltu.mutation.SetStatus(u)
+	return ltu
+}
+
+// SetNillableStatus sets the "status" field if the given value is not nil.
+func (ltu *LabelTaggingUpdate) SetNillableStatus(u *uint8) *LabelTaggingUpdate {
+	if u != nil {
+		ltu.SetStatus(*u)
+	}
+	return ltu
+}
+
+// AddStatus adds u to the "status" field.
+func (ltu *LabelTaggingUpdate) AddStatus(u int8) *LabelTaggingUpdate {
+	ltu.mutation.AddStatus(u)
+	return ltu
+}
+
+// ClearStatus clears the value of the "status" field.
+func (ltu *LabelTaggingUpdate) ClearStatus() *LabelTaggingUpdate {
+	ltu.mutation.ClearStatus()
+	return ltu
+}
+
+// SetDeletedAt sets the "deleted_at" field.
+func (ltu *LabelTaggingUpdate) SetDeletedAt(t time.Time) *LabelTaggingUpdate {
+	ltu.mutation.SetDeletedAt(t)
+	return ltu
+}
+
+// SetNillableDeletedAt sets the "deleted_at" field if the given value is not nil.
+func (ltu *LabelTaggingUpdate) SetNillableDeletedAt(t *time.Time) *LabelTaggingUpdate {
+	if t != nil {
+		ltu.SetDeletedAt(*t)
+	}
+	return ltu
+}
+
+// ClearDeletedAt clears the value of the "deleted_at" field.
+func (ltu *LabelTaggingUpdate) ClearDeletedAt() *LabelTaggingUpdate {
+	ltu.mutation.ClearDeletedAt()
+	return ltu
+}
+
+// SetOrganizationID sets the "organization_id" field.
+func (ltu *LabelTaggingUpdate) SetOrganizationID(u uint64) *LabelTaggingUpdate {
+	ltu.mutation.ResetOrganizationID()
+	ltu.mutation.SetOrganizationID(u)
+	return ltu
+}
+
+// SetNillableOrganizationID sets the "organization_id" field if the given value is not nil.
+func (ltu *LabelTaggingUpdate) SetNillableOrganizationID(u *uint64) *LabelTaggingUpdate {
+	if u != nil {
+		ltu.SetOrganizationID(*u)
+	}
+	return ltu
+}
+
+// AddOrganizationID adds u to the "organization_id" field.
+func (ltu *LabelTaggingUpdate) AddOrganizationID(u int64) *LabelTaggingUpdate {
+	ltu.mutation.AddOrganizationID(u)
+	return ltu
+}
+
+// SetType sets the "type" field.
+func (ltu *LabelTaggingUpdate) SetType(i int) *LabelTaggingUpdate {
+	ltu.mutation.ResetType()
+	ltu.mutation.SetType(i)
+	return ltu
+}
+
+// SetNillableType sets the "type" field if the given value is not nil.
+func (ltu *LabelTaggingUpdate) SetNillableType(i *int) *LabelTaggingUpdate {
+	if i != nil {
+		ltu.SetType(*i)
+	}
+	return ltu
+}
+
+// AddType adds i to the "type" field.
+func (ltu *LabelTaggingUpdate) AddType(i int) *LabelTaggingUpdate {
+	ltu.mutation.AddType(i)
+	return ltu
+}
+
+// SetConditions sets the "conditions" field.
+func (ltu *LabelTaggingUpdate) SetConditions(s string) *LabelTaggingUpdate {
+	ltu.mutation.SetConditions(s)
+	return ltu
+}
+
+// SetNillableConditions sets the "conditions" field if the given value is not nil.
+func (ltu *LabelTaggingUpdate) SetNillableConditions(s *string) *LabelTaggingUpdate {
+	if s != nil {
+		ltu.SetConditions(*s)
+	}
+	return ltu
+}
+
+// SetActionLabelAdd sets the "action_label_add" field.
+func (ltu *LabelTaggingUpdate) SetActionLabelAdd(u []uint64) *LabelTaggingUpdate {
+	ltu.mutation.SetActionLabelAdd(u)
+	return ltu
+}
+
+// AppendActionLabelAdd appends u to the "action_label_add" field.
+func (ltu *LabelTaggingUpdate) AppendActionLabelAdd(u []uint64) *LabelTaggingUpdate {
+	ltu.mutation.AppendActionLabelAdd(u)
+	return ltu
+}
+
+// ClearActionLabelAdd clears the value of the "action_label_add" field.
+func (ltu *LabelTaggingUpdate) ClearActionLabelAdd() *LabelTaggingUpdate {
+	ltu.mutation.ClearActionLabelAdd()
+	return ltu
+}
+
+// SetActionLabelDel sets the "action_label_del" field.
+func (ltu *LabelTaggingUpdate) SetActionLabelDel(u []uint64) *LabelTaggingUpdate {
+	ltu.mutation.SetActionLabelDel(u)
+	return ltu
+}
+
+// AppendActionLabelDel appends u to the "action_label_del" field.
+func (ltu *LabelTaggingUpdate) AppendActionLabelDel(u []uint64) *LabelTaggingUpdate {
+	ltu.mutation.AppendActionLabelDel(u)
+	return ltu
+}
+
+// ClearActionLabelDel clears the value of the "action_label_del" field.
+func (ltu *LabelTaggingUpdate) ClearActionLabelDel() *LabelTaggingUpdate {
+	ltu.mutation.ClearActionLabelDel()
+	return ltu
+}
+
+// Mutation returns the LabelTaggingMutation object of the builder.
+func (ltu *LabelTaggingUpdate) Mutation() *LabelTaggingMutation {
+	return ltu.mutation
+}
+
+// Save executes the query and returns the number of nodes affected by the update operation.
+func (ltu *LabelTaggingUpdate) Save(ctx context.Context) (int, error) {
+	if err := ltu.defaults(); err != nil {
+		return 0, err
+	}
+	return withHooks(ctx, ltu.sqlSave, ltu.mutation, ltu.hooks)
+}
+
+// SaveX is like Save, but panics if an error occurs.
+func (ltu *LabelTaggingUpdate) SaveX(ctx context.Context) int {
+	affected, err := ltu.Save(ctx)
+	if err != nil {
+		panic(err)
+	}
+	return affected
+}
+
+// Exec executes the query.
+func (ltu *LabelTaggingUpdate) Exec(ctx context.Context) error {
+	_, err := ltu.Save(ctx)
+	return err
+}
+
+// ExecX is like Exec, but panics if an error occurs.
+func (ltu *LabelTaggingUpdate) ExecX(ctx context.Context) {
+	if err := ltu.Exec(ctx); err != nil {
+		panic(err)
+	}
+}
+
+// defaults sets the default values of the builder before save.
+func (ltu *LabelTaggingUpdate) defaults() error {
+	if _, ok := ltu.mutation.UpdatedAt(); !ok {
+		if labeltagging.UpdateDefaultUpdatedAt == nil {
+			return fmt.Errorf("ent: uninitialized labeltagging.UpdateDefaultUpdatedAt (forgotten import ent/runtime?)")
+		}
+		v := labeltagging.UpdateDefaultUpdatedAt()
+		ltu.mutation.SetUpdatedAt(v)
+	}
+	return nil
+}
+
+func (ltu *LabelTaggingUpdate) sqlSave(ctx context.Context) (n int, err error) {
+	_spec := sqlgraph.NewUpdateSpec(labeltagging.Table, labeltagging.Columns, sqlgraph.NewFieldSpec(labeltagging.FieldID, field.TypeUint64))
+	if ps := ltu.mutation.predicates; len(ps) > 0 {
+		_spec.Predicate = func(selector *sql.Selector) {
+			for i := range ps {
+				ps[i](selector)
+			}
+		}
+	}
+	if value, ok := ltu.mutation.UpdatedAt(); ok {
+		_spec.SetField(labeltagging.FieldUpdatedAt, field.TypeTime, value)
+	}
+	if value, ok := ltu.mutation.Status(); ok {
+		_spec.SetField(labeltagging.FieldStatus, field.TypeUint8, value)
+	}
+	if value, ok := ltu.mutation.AddedStatus(); ok {
+		_spec.AddField(labeltagging.FieldStatus, field.TypeUint8, value)
+	}
+	if ltu.mutation.StatusCleared() {
+		_spec.ClearField(labeltagging.FieldStatus, field.TypeUint8)
+	}
+	if value, ok := ltu.mutation.DeletedAt(); ok {
+		_spec.SetField(labeltagging.FieldDeletedAt, field.TypeTime, value)
+	}
+	if ltu.mutation.DeletedAtCleared() {
+		_spec.ClearField(labeltagging.FieldDeletedAt, field.TypeTime)
+	}
+	if value, ok := ltu.mutation.OrganizationID(); ok {
+		_spec.SetField(labeltagging.FieldOrganizationID, field.TypeUint64, value)
+	}
+	if value, ok := ltu.mutation.AddedOrganizationID(); ok {
+		_spec.AddField(labeltagging.FieldOrganizationID, field.TypeUint64, value)
+	}
+	if value, ok := ltu.mutation.GetType(); ok {
+		_spec.SetField(labeltagging.FieldType, field.TypeInt, value)
+	}
+	if value, ok := ltu.mutation.AddedType(); ok {
+		_spec.AddField(labeltagging.FieldType, field.TypeInt, value)
+	}
+	if value, ok := ltu.mutation.Conditions(); ok {
+		_spec.SetField(labeltagging.FieldConditions, field.TypeString, value)
+	}
+	if value, ok := ltu.mutation.ActionLabelAdd(); ok {
+		_spec.SetField(labeltagging.FieldActionLabelAdd, field.TypeJSON, value)
+	}
+	if value, ok := ltu.mutation.AppendedActionLabelAdd(); ok {
+		_spec.AddModifier(func(u *sql.UpdateBuilder) {
+			sqljson.Append(u, labeltagging.FieldActionLabelAdd, value)
+		})
+	}
+	if ltu.mutation.ActionLabelAddCleared() {
+		_spec.ClearField(labeltagging.FieldActionLabelAdd, field.TypeJSON)
+	}
+	if value, ok := ltu.mutation.ActionLabelDel(); ok {
+		_spec.SetField(labeltagging.FieldActionLabelDel, field.TypeJSON, value)
+	}
+	if value, ok := ltu.mutation.AppendedActionLabelDel(); ok {
+		_spec.AddModifier(func(u *sql.UpdateBuilder) {
+			sqljson.Append(u, labeltagging.FieldActionLabelDel, value)
+		})
+	}
+	if ltu.mutation.ActionLabelDelCleared() {
+		_spec.ClearField(labeltagging.FieldActionLabelDel, field.TypeJSON)
+	}
+	if n, err = sqlgraph.UpdateNodes(ctx, ltu.driver, _spec); err != nil {
+		if _, ok := err.(*sqlgraph.NotFoundError); ok {
+			err = &NotFoundError{labeltagging.Label}
+		} else if sqlgraph.IsConstraintError(err) {
+			err = &ConstraintError{msg: err.Error(), wrap: err}
+		}
+		return 0, err
+	}
+	ltu.mutation.done = true
+	return n, nil
+}
+
+// LabelTaggingUpdateOne is the builder for updating a single LabelTagging entity.
+type LabelTaggingUpdateOne struct {
+	config
+	fields   []string
+	hooks    []Hook
+	mutation *LabelTaggingMutation
+}
+
+// SetUpdatedAt sets the "updated_at" field.
+func (ltuo *LabelTaggingUpdateOne) SetUpdatedAt(t time.Time) *LabelTaggingUpdateOne {
+	ltuo.mutation.SetUpdatedAt(t)
+	return ltuo
+}
+
+// SetStatus sets the "status" field.
+func (ltuo *LabelTaggingUpdateOne) SetStatus(u uint8) *LabelTaggingUpdateOne {
+	ltuo.mutation.ResetStatus()
+	ltuo.mutation.SetStatus(u)
+	return ltuo
+}
+
+// SetNillableStatus sets the "status" field if the given value is not nil.
+func (ltuo *LabelTaggingUpdateOne) SetNillableStatus(u *uint8) *LabelTaggingUpdateOne {
+	if u != nil {
+		ltuo.SetStatus(*u)
+	}
+	return ltuo
+}
+
+// AddStatus adds u to the "status" field.
+func (ltuo *LabelTaggingUpdateOne) AddStatus(u int8) *LabelTaggingUpdateOne {
+	ltuo.mutation.AddStatus(u)
+	return ltuo
+}
+
+// ClearStatus clears the value of the "status" field.
+func (ltuo *LabelTaggingUpdateOne) ClearStatus() *LabelTaggingUpdateOne {
+	ltuo.mutation.ClearStatus()
+	return ltuo
+}
+
+// SetDeletedAt sets the "deleted_at" field.
+func (ltuo *LabelTaggingUpdateOne) SetDeletedAt(t time.Time) *LabelTaggingUpdateOne {
+	ltuo.mutation.SetDeletedAt(t)
+	return ltuo
+}
+
+// SetNillableDeletedAt sets the "deleted_at" field if the given value is not nil.
+func (ltuo *LabelTaggingUpdateOne) SetNillableDeletedAt(t *time.Time) *LabelTaggingUpdateOne {
+	if t != nil {
+		ltuo.SetDeletedAt(*t)
+	}
+	return ltuo
+}
+
+// ClearDeletedAt clears the value of the "deleted_at" field.
+func (ltuo *LabelTaggingUpdateOne) ClearDeletedAt() *LabelTaggingUpdateOne {
+	ltuo.mutation.ClearDeletedAt()
+	return ltuo
+}
+
+// SetOrganizationID sets the "organization_id" field.
+func (ltuo *LabelTaggingUpdateOne) SetOrganizationID(u uint64) *LabelTaggingUpdateOne {
+	ltuo.mutation.ResetOrganizationID()
+	ltuo.mutation.SetOrganizationID(u)
+	return ltuo
+}
+
+// SetNillableOrganizationID sets the "organization_id" field if the given value is not nil.
+func (ltuo *LabelTaggingUpdateOne) SetNillableOrganizationID(u *uint64) *LabelTaggingUpdateOne {
+	if u != nil {
+		ltuo.SetOrganizationID(*u)
+	}
+	return ltuo
+}
+
+// AddOrganizationID adds u to the "organization_id" field.
+func (ltuo *LabelTaggingUpdateOne) AddOrganizationID(u int64) *LabelTaggingUpdateOne {
+	ltuo.mutation.AddOrganizationID(u)
+	return ltuo
+}
+
+// SetType sets the "type" field.
+func (ltuo *LabelTaggingUpdateOne) SetType(i int) *LabelTaggingUpdateOne {
+	ltuo.mutation.ResetType()
+	ltuo.mutation.SetType(i)
+	return ltuo
+}
+
+// SetNillableType sets the "type" field if the given value is not nil.
+func (ltuo *LabelTaggingUpdateOne) SetNillableType(i *int) *LabelTaggingUpdateOne {
+	if i != nil {
+		ltuo.SetType(*i)
+	}
+	return ltuo
+}
+
+// AddType adds i to the "type" field.
+func (ltuo *LabelTaggingUpdateOne) AddType(i int) *LabelTaggingUpdateOne {
+	ltuo.mutation.AddType(i)
+	return ltuo
+}
+
+// SetConditions sets the "conditions" field.
+func (ltuo *LabelTaggingUpdateOne) SetConditions(s string) *LabelTaggingUpdateOne {
+	ltuo.mutation.SetConditions(s)
+	return ltuo
+}
+
+// SetNillableConditions sets the "conditions" field if the given value is not nil.
+func (ltuo *LabelTaggingUpdateOne) SetNillableConditions(s *string) *LabelTaggingUpdateOne {
+	if s != nil {
+		ltuo.SetConditions(*s)
+	}
+	return ltuo
+}
+
+// SetActionLabelAdd sets the "action_label_add" field.
+func (ltuo *LabelTaggingUpdateOne) SetActionLabelAdd(u []uint64) *LabelTaggingUpdateOne {
+	ltuo.mutation.SetActionLabelAdd(u)
+	return ltuo
+}
+
+// AppendActionLabelAdd appends u to the "action_label_add" field.
+func (ltuo *LabelTaggingUpdateOne) AppendActionLabelAdd(u []uint64) *LabelTaggingUpdateOne {
+	ltuo.mutation.AppendActionLabelAdd(u)
+	return ltuo
+}
+
+// ClearActionLabelAdd clears the value of the "action_label_add" field.
+func (ltuo *LabelTaggingUpdateOne) ClearActionLabelAdd() *LabelTaggingUpdateOne {
+	ltuo.mutation.ClearActionLabelAdd()
+	return ltuo
+}
+
+// SetActionLabelDel sets the "action_label_del" field.
+func (ltuo *LabelTaggingUpdateOne) SetActionLabelDel(u []uint64) *LabelTaggingUpdateOne {
+	ltuo.mutation.SetActionLabelDel(u)
+	return ltuo
+}
+
+// AppendActionLabelDel appends u to the "action_label_del" field.
+func (ltuo *LabelTaggingUpdateOne) AppendActionLabelDel(u []uint64) *LabelTaggingUpdateOne {
+	ltuo.mutation.AppendActionLabelDel(u)
+	return ltuo
+}
+
+// ClearActionLabelDel clears the value of the "action_label_del" field.
+func (ltuo *LabelTaggingUpdateOne) ClearActionLabelDel() *LabelTaggingUpdateOne {
+	ltuo.mutation.ClearActionLabelDel()
+	return ltuo
+}
+
+// Mutation returns the LabelTaggingMutation object of the builder.
+func (ltuo *LabelTaggingUpdateOne) Mutation() *LabelTaggingMutation {
+	return ltuo.mutation
+}
+
+// Where appends a list predicates to the LabelTaggingUpdate builder.
+func (ltuo *LabelTaggingUpdateOne) Where(ps ...predicate.LabelTagging) *LabelTaggingUpdateOne {
+	ltuo.mutation.Where(ps...)
+	return ltuo
+}
+
+// Select allows selecting one or more fields (columns) of the returned entity.
+// The default is selecting all fields defined in the entity schema.
+func (ltuo *LabelTaggingUpdateOne) Select(field string, fields ...string) *LabelTaggingUpdateOne {
+	ltuo.fields = append([]string{field}, fields...)
+	return ltuo
+}
+
+// Save executes the query and returns the updated LabelTagging entity.
+func (ltuo *LabelTaggingUpdateOne) Save(ctx context.Context) (*LabelTagging, error) {
+	if err := ltuo.defaults(); err != nil {
+		return nil, err
+	}
+	return withHooks(ctx, ltuo.sqlSave, ltuo.mutation, ltuo.hooks)
+}
+
+// SaveX is like Save, but panics if an error occurs.
+func (ltuo *LabelTaggingUpdateOne) SaveX(ctx context.Context) *LabelTagging {
+	node, err := ltuo.Save(ctx)
+	if err != nil {
+		panic(err)
+	}
+	return node
+}
+
+// Exec executes the query on the entity.
+func (ltuo *LabelTaggingUpdateOne) Exec(ctx context.Context) error {
+	_, err := ltuo.Save(ctx)
+	return err
+}
+
+// ExecX is like Exec, but panics if an error occurs.
+func (ltuo *LabelTaggingUpdateOne) ExecX(ctx context.Context) {
+	if err := ltuo.Exec(ctx); err != nil {
+		panic(err)
+	}
+}
+
+// defaults sets the default values of the builder before save.
+func (ltuo *LabelTaggingUpdateOne) defaults() error {
+	if _, ok := ltuo.mutation.UpdatedAt(); !ok {
+		if labeltagging.UpdateDefaultUpdatedAt == nil {
+			return fmt.Errorf("ent: uninitialized labeltagging.UpdateDefaultUpdatedAt (forgotten import ent/runtime?)")
+		}
+		v := labeltagging.UpdateDefaultUpdatedAt()
+		ltuo.mutation.SetUpdatedAt(v)
+	}
+	return nil
+}
+
+func (ltuo *LabelTaggingUpdateOne) sqlSave(ctx context.Context) (_node *LabelTagging, err error) {
+	_spec := sqlgraph.NewUpdateSpec(labeltagging.Table, labeltagging.Columns, sqlgraph.NewFieldSpec(labeltagging.FieldID, field.TypeUint64))
+	id, ok := ltuo.mutation.ID()
+	if !ok {
+		return nil, &ValidationError{Name: "id", err: errors.New(`ent: missing "LabelTagging.id" for update`)}
+	}
+	_spec.Node.ID.Value = id
+	if fields := ltuo.fields; len(fields) > 0 {
+		_spec.Node.Columns = make([]string, 0, len(fields))
+		_spec.Node.Columns = append(_spec.Node.Columns, labeltagging.FieldID)
+		for _, f := range fields {
+			if !labeltagging.ValidColumn(f) {
+				return nil, &ValidationError{Name: f, err: fmt.Errorf("ent: invalid field %q for query", f)}
+			}
+			if f != labeltagging.FieldID {
+				_spec.Node.Columns = append(_spec.Node.Columns, f)
+			}
+		}
+	}
+	if ps := ltuo.mutation.predicates; len(ps) > 0 {
+		_spec.Predicate = func(selector *sql.Selector) {
+			for i := range ps {
+				ps[i](selector)
+			}
+		}
+	}
+	if value, ok := ltuo.mutation.UpdatedAt(); ok {
+		_spec.SetField(labeltagging.FieldUpdatedAt, field.TypeTime, value)
+	}
+	if value, ok := ltuo.mutation.Status(); ok {
+		_spec.SetField(labeltagging.FieldStatus, field.TypeUint8, value)
+	}
+	if value, ok := ltuo.mutation.AddedStatus(); ok {
+		_spec.AddField(labeltagging.FieldStatus, field.TypeUint8, value)
+	}
+	if ltuo.mutation.StatusCleared() {
+		_spec.ClearField(labeltagging.FieldStatus, field.TypeUint8)
+	}
+	if value, ok := ltuo.mutation.DeletedAt(); ok {
+		_spec.SetField(labeltagging.FieldDeletedAt, field.TypeTime, value)
+	}
+	if ltuo.mutation.DeletedAtCleared() {
+		_spec.ClearField(labeltagging.FieldDeletedAt, field.TypeTime)
+	}
+	if value, ok := ltuo.mutation.OrganizationID(); ok {
+		_spec.SetField(labeltagging.FieldOrganizationID, field.TypeUint64, value)
+	}
+	if value, ok := ltuo.mutation.AddedOrganizationID(); ok {
+		_spec.AddField(labeltagging.FieldOrganizationID, field.TypeUint64, value)
+	}
+	if value, ok := ltuo.mutation.GetType(); ok {
+		_spec.SetField(labeltagging.FieldType, field.TypeInt, value)
+	}
+	if value, ok := ltuo.mutation.AddedType(); ok {
+		_spec.AddField(labeltagging.FieldType, field.TypeInt, value)
+	}
+	if value, ok := ltuo.mutation.Conditions(); ok {
+		_spec.SetField(labeltagging.FieldConditions, field.TypeString, value)
+	}
+	if value, ok := ltuo.mutation.ActionLabelAdd(); ok {
+		_spec.SetField(labeltagging.FieldActionLabelAdd, field.TypeJSON, value)
+	}
+	if value, ok := ltuo.mutation.AppendedActionLabelAdd(); ok {
+		_spec.AddModifier(func(u *sql.UpdateBuilder) {
+			sqljson.Append(u, labeltagging.FieldActionLabelAdd, value)
+		})
+	}
+	if ltuo.mutation.ActionLabelAddCleared() {
+		_spec.ClearField(labeltagging.FieldActionLabelAdd, field.TypeJSON)
+	}
+	if value, ok := ltuo.mutation.ActionLabelDel(); ok {
+		_spec.SetField(labeltagging.FieldActionLabelDel, field.TypeJSON, value)
+	}
+	if value, ok := ltuo.mutation.AppendedActionLabelDel(); ok {
+		_spec.AddModifier(func(u *sql.UpdateBuilder) {
+			sqljson.Append(u, labeltagging.FieldActionLabelDel, value)
+		})
+	}
+	if ltuo.mutation.ActionLabelDelCleared() {
+		_spec.ClearField(labeltagging.FieldActionLabelDel, field.TypeJSON)
+	}
+	_node = &LabelTagging{config: ltuo.config}
+	_spec.Assign = _node.assignValues
+	_spec.ScanValues = _node.scanValues
+	if err = sqlgraph.UpdateNode(ctx, ltuo.driver, _spec); err != nil {
+		if _, ok := err.(*sqlgraph.NotFoundError); ok {
+			err = &NotFoundError{labeltagging.Label}
+		} else if sqlgraph.IsConstraintError(err) {
+			err = &ConstraintError{msg: err.Error(), wrap: err}
+		}
+		return nil, err
+	}
+	ltuo.mutation.done = true
+	return _node, nil
+}

+ 27 - 5
ent/migrate/schema.go

@@ -442,7 +442,6 @@ var (
 		{Name: "created_at", Type: field.TypeTime, Comment: "Create Time | 创建日期"},
 		{Name: "updated_at", Type: field.TypeTime, Comment: "Update Time | 修改日期"},
 		{Name: "status", Type: field.TypeUint8, Nullable: true, Comment: "Status 1: normal 2: ban | 状态 1 正常 2 禁用", Default: 1},
-		{Name: "deleted_at", Type: field.TypeTime, Nullable: true, Comment: "Delete Time | 删除日期"},
 		{Name: "organization_id", Type: field.TypeUint64, Nullable: true, Comment: "机构 ID", Default: 1},
 		{Name: "contact_id", Type: field.TypeUint64, Comment: "联系人 ID", Default: 1},
 		{Name: "label_id", Type: field.TypeUint64, Comment: "标签 ID", Default: 1},
@@ -455,13 +454,13 @@ var (
 		ForeignKeys: []*schema.ForeignKey{
 			{
 				Symbol:     "label_relationship_contact_contact_relationships",
-				Columns:    []*schema.Column{LabelRelationshipColumns[6]},
+				Columns:    []*schema.Column{LabelRelationshipColumns[5]},
 				RefColumns: []*schema.Column{ContactColumns[0]},
 				OnDelete:   schema.NoAction,
 			},
 			{
 				Symbol:     "label_relationship_label_label_relationships",
-				Columns:    []*schema.Column{LabelRelationshipColumns[7]},
+				Columns:    []*schema.Column{LabelRelationshipColumns[6]},
 				RefColumns: []*schema.Column{LabelColumns[0]},
 				OnDelete:   schema.NoAction,
 			},
@@ -470,15 +469,34 @@ var (
 			{
 				Name:    "labelrelationship_label_id",
 				Unique:  false,
-				Columns: []*schema.Column{LabelRelationshipColumns[7]},
+				Columns: []*schema.Column{LabelRelationshipColumns[6]},
 			},
 			{
 				Name:    "labelrelationship_contact_id",
 				Unique:  false,
-				Columns: []*schema.Column{LabelRelationshipColumns[6]},
+				Columns: []*schema.Column{LabelRelationshipColumns[5]},
 			},
 		},
 	}
+	// LabelTaggingColumns holds the columns for the "label_tagging" table.
+	LabelTaggingColumns = []*schema.Column{
+		{Name: "id", Type: field.TypeUint64, Increment: true},
+		{Name: "created_at", Type: field.TypeTime, Comment: "Create Time | 创建日期"},
+		{Name: "updated_at", Type: field.TypeTime, Comment: "Update Time | 修改日期"},
+		{Name: "status", Type: field.TypeUint8, Nullable: true, Comment: "Status 1: normal 2: ban | 状态 1 正常 2 禁用", Default: 1},
+		{Name: "deleted_at", Type: field.TypeTime, Nullable: true, Comment: "Delete Time | 删除日期"},
+		{Name: "organization_id", Type: field.TypeUint64, Comment: "机构 ID", Default: 1},
+		{Name: "type", Type: field.TypeInt, Comment: "标签类型:1好友,2群组,3公众号,4企业微信联系人", Default: 1},
+		{Name: "conditions", Type: field.TypeString, Comment: "关键词", Default: ""},
+		{Name: "action_label_add", Type: field.TypeJSON, Nullable: true, Comment: "命中后需要打的标签"},
+		{Name: "action_label_del", Type: field.TypeJSON, Nullable: true, Comment: "命中后需要移除的标签"},
+	}
+	// LabelTaggingTable holds the schema information for the "label_tagging" table.
+	LabelTaggingTable = &schema.Table{
+		Name:       "label_tagging",
+		Columns:    LabelTaggingColumns,
+		PrimaryKey: []*schema.Column{LabelTaggingColumns[0]},
+	}
 	// MessagesColumns holds the columns for the "messages" table.
 	MessagesColumns = []*schema.Column{
 		{Name: "id", Type: field.TypeInt, Increment: true},
@@ -1293,6 +1311,7 @@ var (
 		EmployeeConfigTable,
 		LabelTable,
 		LabelRelationshipTable,
+		LabelTaggingTable,
 		MessagesTable,
 		MessageRecordsTable,
 		MsgTable,
@@ -1366,6 +1385,9 @@ func init() {
 	LabelRelationshipTable.Annotation = &entsql.Annotation{
 		Table: "label_relationship",
 	}
+	LabelTaggingTable.Annotation = &entsql.Annotation{
+		Table: "label_tagging",
+	}
 	MessagesTable.Annotation = &entsql.Annotation{
 		Table: "messages",
 	}

+ 983 - 74
ent/mutation.go

@@ -24,6 +24,7 @@ import (
 	"wechat-api/ent/employeeconfig"
 	"wechat-api/ent/label"
 	"wechat-api/ent/labelrelationship"
+	"wechat-api/ent/labeltagging"
 	"wechat-api/ent/message"
 	"wechat-api/ent/messagerecords"
 	"wechat-api/ent/msg"
@@ -76,6 +77,7 @@ const (
 	TypeEmployeeConfig      = "EmployeeConfig"
 	TypeLabel               = "Label"
 	TypeLabelRelationship   = "LabelRelationship"
+	TypeLabelTagging        = "LabelTagging"
 	TypeMessage             = "Message"
 	TypeMessageRecords      = "MessageRecords"
 	TypeMsg                 = "Msg"
@@ -15860,7 +15862,6 @@ type LabelRelationshipMutation struct {
 	updated_at         *time.Time
 	status             *uint8
 	addstatus          *int8
-	deleted_at         *time.Time
 	organization_id    *uint64
 	addorganization_id *int64
 	clearedFields      map[string]struct{}
@@ -16119,55 +16120,6 @@ func (m *LabelRelationshipMutation) ResetStatus() {
 	delete(m.clearedFields, labelrelationship.FieldStatus)
 }
 
-// SetDeletedAt sets the "deleted_at" field.
-func (m *LabelRelationshipMutation) SetDeletedAt(t time.Time) {
-	m.deleted_at = &t
-}
-
-// DeletedAt returns the value of the "deleted_at" field in the mutation.
-func (m *LabelRelationshipMutation) DeletedAt() (r time.Time, exists bool) {
-	v := m.deleted_at
-	if v == nil {
-		return
-	}
-	return *v, true
-}
-
-// OldDeletedAt returns the old "deleted_at" field's value of the LabelRelationship entity.
-// If the LabelRelationship object wasn't provided to the builder, the object is fetched from the database.
-// An error is returned if the mutation operation is not UpdateOne, or the database query fails.
-func (m *LabelRelationshipMutation) OldDeletedAt(ctx context.Context) (v time.Time, err error) {
-	if !m.op.Is(OpUpdateOne) {
-		return v, errors.New("OldDeletedAt is only allowed on UpdateOne operations")
-	}
-	if m.id == nil || m.oldValue == nil {
-		return v, errors.New("OldDeletedAt requires an ID field in the mutation")
-	}
-	oldValue, err := m.oldValue(ctx)
-	if err != nil {
-		return v, fmt.Errorf("querying old value for OldDeletedAt: %w", err)
-	}
-	return oldValue.DeletedAt, nil
-}
-
-// ClearDeletedAt clears the value of the "deleted_at" field.
-func (m *LabelRelationshipMutation) ClearDeletedAt() {
-	m.deleted_at = nil
-	m.clearedFields[labelrelationship.FieldDeletedAt] = struct{}{}
-}
-
-// DeletedAtCleared returns if the "deleted_at" field was cleared in this mutation.
-func (m *LabelRelationshipMutation) DeletedAtCleared() bool {
-	_, ok := m.clearedFields[labelrelationship.FieldDeletedAt]
-	return ok
-}
-
-// ResetDeletedAt resets all changes to the "deleted_at" field.
-func (m *LabelRelationshipMutation) ResetDeletedAt() {
-	m.deleted_at = nil
-	delete(m.clearedFields, labelrelationship.FieldDeletedAt)
-}
-
 // SetLabelID sets the "label_id" field.
 func (m *LabelRelationshipMutation) SetLabelID(u uint64) {
 	m.labels = &u
@@ -16424,7 +16376,7 @@ func (m *LabelRelationshipMutation) Type() string {
 // order to get all numeric fields that were incremented/decremented, call
 // AddedFields().
 func (m *LabelRelationshipMutation) Fields() []string {
-	fields := make([]string, 0, 7)
+	fields := make([]string, 0, 6)
 	if m.created_at != nil {
 		fields = append(fields, labelrelationship.FieldCreatedAt)
 	}
@@ -16434,9 +16386,6 @@ func (m *LabelRelationshipMutation) Fields() []string {
 	if m.status != nil {
 		fields = append(fields, labelrelationship.FieldStatus)
 	}
-	if m.deleted_at != nil {
-		fields = append(fields, labelrelationship.FieldDeletedAt)
-	}
 	if m.labels != nil {
 		fields = append(fields, labelrelationship.FieldLabelID)
 	}
@@ -16460,8 +16409,6 @@ func (m *LabelRelationshipMutation) Field(name string) (ent.Value, bool) {
 		return m.UpdatedAt()
 	case labelrelationship.FieldStatus:
 		return m.Status()
-	case labelrelationship.FieldDeletedAt:
-		return m.DeletedAt()
 	case labelrelationship.FieldLabelID:
 		return m.LabelID()
 	case labelrelationship.FieldContactID:
@@ -16483,8 +16430,6 @@ func (m *LabelRelationshipMutation) OldField(ctx context.Context, name string) (
 		return m.OldUpdatedAt(ctx)
 	case labelrelationship.FieldStatus:
 		return m.OldStatus(ctx)
-	case labelrelationship.FieldDeletedAt:
-		return m.OldDeletedAt(ctx)
 	case labelrelationship.FieldLabelID:
 		return m.OldLabelID(ctx)
 	case labelrelationship.FieldContactID:
@@ -16521,13 +16466,6 @@ func (m *LabelRelationshipMutation) SetField(name string, value ent.Value) error
 		}
 		m.SetStatus(v)
 		return nil
-	case labelrelationship.FieldDeletedAt:
-		v, ok := value.(time.Time)
-		if !ok {
-			return fmt.Errorf("unexpected type %T for field %s", value, name)
-		}
-		m.SetDeletedAt(v)
-		return nil
 	case labelrelationship.FieldLabelID:
 		v, ok := value.(uint64)
 		if !ok {
@@ -16609,9 +16547,6 @@ func (m *LabelRelationshipMutation) ClearedFields() []string {
 	if m.FieldCleared(labelrelationship.FieldStatus) {
 		fields = append(fields, labelrelationship.FieldStatus)
 	}
-	if m.FieldCleared(labelrelationship.FieldDeletedAt) {
-		fields = append(fields, labelrelationship.FieldDeletedAt)
-	}
 	if m.FieldCleared(labelrelationship.FieldOrganizationID) {
 		fields = append(fields, labelrelationship.FieldOrganizationID)
 	}
@@ -16632,9 +16567,6 @@ func (m *LabelRelationshipMutation) ClearField(name string) error {
 	case labelrelationship.FieldStatus:
 		m.ClearStatus()
 		return nil
-	case labelrelationship.FieldDeletedAt:
-		m.ClearDeletedAt()
-		return nil
 	case labelrelationship.FieldOrganizationID:
 		m.ClearOrganizationID()
 		return nil
@@ -16655,9 +16587,6 @@ func (m *LabelRelationshipMutation) ResetField(name string) error {
 	case labelrelationship.FieldStatus:
 		m.ResetStatus()
 		return nil
-	case labelrelationship.FieldDeletedAt:
-		m.ResetDeletedAt()
-		return nil
 	case labelrelationship.FieldLabelID:
 		m.ResetLabelID()
 		return nil
@@ -16763,6 +16692,986 @@ func (m *LabelRelationshipMutation) ResetEdge(name string) error {
 	return fmt.Errorf("unknown LabelRelationship edge %s", name)
 }
 
+// LabelTaggingMutation represents an operation that mutates the LabelTagging nodes in the graph.
+type LabelTaggingMutation struct {
+	config
+	op                     Op
+	typ                    string
+	id                     *uint64
+	created_at             *time.Time
+	updated_at             *time.Time
+	status                 *uint8
+	addstatus              *int8
+	deleted_at             *time.Time
+	organization_id        *uint64
+	addorganization_id     *int64
+	_type                  *int
+	add_type               *int
+	conditions             *string
+	action_label_add       *[]uint64
+	appendaction_label_add []uint64
+	action_label_del       *[]uint64
+	appendaction_label_del []uint64
+	clearedFields          map[string]struct{}
+	done                   bool
+	oldValue               func(context.Context) (*LabelTagging, error)
+	predicates             []predicate.LabelTagging
+}
+
+var _ ent.Mutation = (*LabelTaggingMutation)(nil)
+
+// labeltaggingOption allows management of the mutation configuration using functional options.
+type labeltaggingOption func(*LabelTaggingMutation)
+
+// newLabelTaggingMutation creates new mutation for the LabelTagging entity.
+func newLabelTaggingMutation(c config, op Op, opts ...labeltaggingOption) *LabelTaggingMutation {
+	m := &LabelTaggingMutation{
+		config:        c,
+		op:            op,
+		typ:           TypeLabelTagging,
+		clearedFields: make(map[string]struct{}),
+	}
+	for _, opt := range opts {
+		opt(m)
+	}
+	return m
+}
+
+// withLabelTaggingID sets the ID field of the mutation.
+func withLabelTaggingID(id uint64) labeltaggingOption {
+	return func(m *LabelTaggingMutation) {
+		var (
+			err   error
+			once  sync.Once
+			value *LabelTagging
+		)
+		m.oldValue = func(ctx context.Context) (*LabelTagging, error) {
+			once.Do(func() {
+				if m.done {
+					err = errors.New("querying old values post mutation is not allowed")
+				} else {
+					value, err = m.Client().LabelTagging.Get(ctx, id)
+				}
+			})
+			return value, err
+		}
+		m.id = &id
+	}
+}
+
+// withLabelTagging sets the old LabelTagging of the mutation.
+func withLabelTagging(node *LabelTagging) labeltaggingOption {
+	return func(m *LabelTaggingMutation) {
+		m.oldValue = func(context.Context) (*LabelTagging, error) {
+			return node, nil
+		}
+		m.id = &node.ID
+	}
+}
+
+// Client returns a new `ent.Client` from the mutation. If the mutation was
+// executed in a transaction (ent.Tx), a transactional client is returned.
+func (m LabelTaggingMutation) Client() *Client {
+	client := &Client{config: m.config}
+	client.init()
+	return client
+}
+
+// Tx returns an `ent.Tx` for mutations that were executed in transactions;
+// it returns an error otherwise.
+func (m LabelTaggingMutation) Tx() (*Tx, error) {
+	if _, ok := m.driver.(*txDriver); !ok {
+		return nil, errors.New("ent: mutation is not running in a transaction")
+	}
+	tx := &Tx{config: m.config}
+	tx.init()
+	return tx, nil
+}
+
+// SetID sets the value of the id field. Note that this
+// operation is only accepted on creation of LabelTagging entities.
+func (m *LabelTaggingMutation) SetID(id uint64) {
+	m.id = &id
+}
+
+// ID returns the ID value in the mutation. Note that the ID is only available
+// if it was provided to the builder or after it was returned from the database.
+func (m *LabelTaggingMutation) ID() (id uint64, exists bool) {
+	if m.id == nil {
+		return
+	}
+	return *m.id, true
+}
+
+// IDs queries the database and returns the entity ids that match the mutation's predicate.
+// That means, if the mutation is applied within a transaction with an isolation level such
+// as sql.LevelSerializable, the returned ids match the ids of the rows that will be updated
+// or updated by the mutation.
+func (m *LabelTaggingMutation) IDs(ctx context.Context) ([]uint64, error) {
+	switch {
+	case m.op.Is(OpUpdateOne | OpDeleteOne):
+		id, exists := m.ID()
+		if exists {
+			return []uint64{id}, nil
+		}
+		fallthrough
+	case m.op.Is(OpUpdate | OpDelete):
+		return m.Client().LabelTagging.Query().Where(m.predicates...).IDs(ctx)
+	default:
+		return nil, fmt.Errorf("IDs is not allowed on %s operations", m.op)
+	}
+}
+
+// SetCreatedAt sets the "created_at" field.
+func (m *LabelTaggingMutation) SetCreatedAt(t time.Time) {
+	m.created_at = &t
+}
+
+// CreatedAt returns the value of the "created_at" field in the mutation.
+func (m *LabelTaggingMutation) CreatedAt() (r time.Time, exists bool) {
+	v := m.created_at
+	if v == nil {
+		return
+	}
+	return *v, true
+}
+
+// OldCreatedAt returns the old "created_at" field's value of the LabelTagging entity.
+// If the LabelTagging object wasn't provided to the builder, the object is fetched from the database.
+// An error is returned if the mutation operation is not UpdateOne, or the database query fails.
+func (m *LabelTaggingMutation) OldCreatedAt(ctx context.Context) (v time.Time, err error) {
+	if !m.op.Is(OpUpdateOne) {
+		return v, errors.New("OldCreatedAt is only allowed on UpdateOne operations")
+	}
+	if m.id == nil || m.oldValue == nil {
+		return v, errors.New("OldCreatedAt requires an ID field in the mutation")
+	}
+	oldValue, err := m.oldValue(ctx)
+	if err != nil {
+		return v, fmt.Errorf("querying old value for OldCreatedAt: %w", err)
+	}
+	return oldValue.CreatedAt, nil
+}
+
+// ResetCreatedAt resets all changes to the "created_at" field.
+func (m *LabelTaggingMutation) ResetCreatedAt() {
+	m.created_at = nil
+}
+
+// SetUpdatedAt sets the "updated_at" field.
+func (m *LabelTaggingMutation) SetUpdatedAt(t time.Time) {
+	m.updated_at = &t
+}
+
+// UpdatedAt returns the value of the "updated_at" field in the mutation.
+func (m *LabelTaggingMutation) UpdatedAt() (r time.Time, exists bool) {
+	v := m.updated_at
+	if v == nil {
+		return
+	}
+	return *v, true
+}
+
+// OldUpdatedAt returns the old "updated_at" field's value of the LabelTagging entity.
+// If the LabelTagging object wasn't provided to the builder, the object is fetched from the database.
+// An error is returned if the mutation operation is not UpdateOne, or the database query fails.
+func (m *LabelTaggingMutation) OldUpdatedAt(ctx context.Context) (v time.Time, err error) {
+	if !m.op.Is(OpUpdateOne) {
+		return v, errors.New("OldUpdatedAt is only allowed on UpdateOne operations")
+	}
+	if m.id == nil || m.oldValue == nil {
+		return v, errors.New("OldUpdatedAt requires an ID field in the mutation")
+	}
+	oldValue, err := m.oldValue(ctx)
+	if err != nil {
+		return v, fmt.Errorf("querying old value for OldUpdatedAt: %w", err)
+	}
+	return oldValue.UpdatedAt, nil
+}
+
+// ResetUpdatedAt resets all changes to the "updated_at" field.
+func (m *LabelTaggingMutation) ResetUpdatedAt() {
+	m.updated_at = nil
+}
+
+// SetStatus sets the "status" field.
+func (m *LabelTaggingMutation) SetStatus(u uint8) {
+	m.status = &u
+	m.addstatus = nil
+}
+
+// Status returns the value of the "status" field in the mutation.
+func (m *LabelTaggingMutation) Status() (r uint8, exists bool) {
+	v := m.status
+	if v == nil {
+		return
+	}
+	return *v, true
+}
+
+// OldStatus returns the old "status" field's value of the LabelTagging entity.
+// If the LabelTagging object wasn't provided to the builder, the object is fetched from the database.
+// An error is returned if the mutation operation is not UpdateOne, or the database query fails.
+func (m *LabelTaggingMutation) OldStatus(ctx context.Context) (v uint8, err error) {
+	if !m.op.Is(OpUpdateOne) {
+		return v, errors.New("OldStatus is only allowed on UpdateOne operations")
+	}
+	if m.id == nil || m.oldValue == nil {
+		return v, errors.New("OldStatus requires an ID field in the mutation")
+	}
+	oldValue, err := m.oldValue(ctx)
+	if err != nil {
+		return v, fmt.Errorf("querying old value for OldStatus: %w", err)
+	}
+	return oldValue.Status, nil
+}
+
+// AddStatus adds u to the "status" field.
+func (m *LabelTaggingMutation) AddStatus(u int8) {
+	if m.addstatus != nil {
+		*m.addstatus += u
+	} else {
+		m.addstatus = &u
+	}
+}
+
+// AddedStatus returns the value that was added to the "status" field in this mutation.
+func (m *LabelTaggingMutation) AddedStatus() (r int8, exists bool) {
+	v := m.addstatus
+	if v == nil {
+		return
+	}
+	return *v, true
+}
+
+// ClearStatus clears the value of the "status" field.
+func (m *LabelTaggingMutation) ClearStatus() {
+	m.status = nil
+	m.addstatus = nil
+	m.clearedFields[labeltagging.FieldStatus] = struct{}{}
+}
+
+// StatusCleared returns if the "status" field was cleared in this mutation.
+func (m *LabelTaggingMutation) StatusCleared() bool {
+	_, ok := m.clearedFields[labeltagging.FieldStatus]
+	return ok
+}
+
+// ResetStatus resets all changes to the "status" field.
+func (m *LabelTaggingMutation) ResetStatus() {
+	m.status = nil
+	m.addstatus = nil
+	delete(m.clearedFields, labeltagging.FieldStatus)
+}
+
+// SetDeletedAt sets the "deleted_at" field.
+func (m *LabelTaggingMutation) SetDeletedAt(t time.Time) {
+	m.deleted_at = &t
+}
+
+// DeletedAt returns the value of the "deleted_at" field in the mutation.
+func (m *LabelTaggingMutation) DeletedAt() (r time.Time, exists bool) {
+	v := m.deleted_at
+	if v == nil {
+		return
+	}
+	return *v, true
+}
+
+// OldDeletedAt returns the old "deleted_at" field's value of the LabelTagging entity.
+// If the LabelTagging object wasn't provided to the builder, the object is fetched from the database.
+// An error is returned if the mutation operation is not UpdateOne, or the database query fails.
+func (m *LabelTaggingMutation) OldDeletedAt(ctx context.Context) (v time.Time, err error) {
+	if !m.op.Is(OpUpdateOne) {
+		return v, errors.New("OldDeletedAt is only allowed on UpdateOne operations")
+	}
+	if m.id == nil || m.oldValue == nil {
+		return v, errors.New("OldDeletedAt requires an ID field in the mutation")
+	}
+	oldValue, err := m.oldValue(ctx)
+	if err != nil {
+		return v, fmt.Errorf("querying old value for OldDeletedAt: %w", err)
+	}
+	return oldValue.DeletedAt, nil
+}
+
+// ClearDeletedAt clears the value of the "deleted_at" field.
+func (m *LabelTaggingMutation) ClearDeletedAt() {
+	m.deleted_at = nil
+	m.clearedFields[labeltagging.FieldDeletedAt] = struct{}{}
+}
+
+// DeletedAtCleared returns if the "deleted_at" field was cleared in this mutation.
+func (m *LabelTaggingMutation) DeletedAtCleared() bool {
+	_, ok := m.clearedFields[labeltagging.FieldDeletedAt]
+	return ok
+}
+
+// ResetDeletedAt resets all changes to the "deleted_at" field.
+func (m *LabelTaggingMutation) ResetDeletedAt() {
+	m.deleted_at = nil
+	delete(m.clearedFields, labeltagging.FieldDeletedAt)
+}
+
+// SetOrganizationID sets the "organization_id" field.
+func (m *LabelTaggingMutation) SetOrganizationID(u uint64) {
+	m.organization_id = &u
+	m.addorganization_id = nil
+}
+
+// OrganizationID returns the value of the "organization_id" field in the mutation.
+func (m *LabelTaggingMutation) OrganizationID() (r uint64, exists bool) {
+	v := m.organization_id
+	if v == nil {
+		return
+	}
+	return *v, true
+}
+
+// OldOrganizationID returns the old "organization_id" field's value of the LabelTagging entity.
+// If the LabelTagging object wasn't provided to the builder, the object is fetched from the database.
+// An error is returned if the mutation operation is not UpdateOne, or the database query fails.
+func (m *LabelTaggingMutation) OldOrganizationID(ctx context.Context) (v uint64, err error) {
+	if !m.op.Is(OpUpdateOne) {
+		return v, errors.New("OldOrganizationID is only allowed on UpdateOne operations")
+	}
+	if m.id == nil || m.oldValue == nil {
+		return v, errors.New("OldOrganizationID requires an ID field in the mutation")
+	}
+	oldValue, err := m.oldValue(ctx)
+	if err != nil {
+		return v, fmt.Errorf("querying old value for OldOrganizationID: %w", err)
+	}
+	return oldValue.OrganizationID, nil
+}
+
+// AddOrganizationID adds u to the "organization_id" field.
+func (m *LabelTaggingMutation) AddOrganizationID(u int64) {
+	if m.addorganization_id != nil {
+		*m.addorganization_id += u
+	} else {
+		m.addorganization_id = &u
+	}
+}
+
+// AddedOrganizationID returns the value that was added to the "organization_id" field in this mutation.
+func (m *LabelTaggingMutation) AddedOrganizationID() (r int64, exists bool) {
+	v := m.addorganization_id
+	if v == nil {
+		return
+	}
+	return *v, true
+}
+
+// ResetOrganizationID resets all changes to the "organization_id" field.
+func (m *LabelTaggingMutation) ResetOrganizationID() {
+	m.organization_id = nil
+	m.addorganization_id = nil
+}
+
+// SetType sets the "type" field.
+func (m *LabelTaggingMutation) SetType(i int) {
+	m._type = &i
+	m.add_type = nil
+}
+
+// GetType returns the value of the "type" field in the mutation.
+func (m *LabelTaggingMutation) GetType() (r int, exists bool) {
+	v := m._type
+	if v == nil {
+		return
+	}
+	return *v, true
+}
+
+// OldType returns the old "type" field's value of the LabelTagging entity.
+// If the LabelTagging object wasn't provided to the builder, the object is fetched from the database.
+// An error is returned if the mutation operation is not UpdateOne, or the database query fails.
+func (m *LabelTaggingMutation) OldType(ctx context.Context) (v int, err error) {
+	if !m.op.Is(OpUpdateOne) {
+		return v, errors.New("OldType is only allowed on UpdateOne operations")
+	}
+	if m.id == nil || m.oldValue == nil {
+		return v, errors.New("OldType requires an ID field in the mutation")
+	}
+	oldValue, err := m.oldValue(ctx)
+	if err != nil {
+		return v, fmt.Errorf("querying old value for OldType: %w", err)
+	}
+	return oldValue.Type, nil
+}
+
+// AddType adds i to the "type" field.
+func (m *LabelTaggingMutation) AddType(i int) {
+	if m.add_type != nil {
+		*m.add_type += i
+	} else {
+		m.add_type = &i
+	}
+}
+
+// AddedType returns the value that was added to the "type" field in this mutation.
+func (m *LabelTaggingMutation) AddedType() (r int, exists bool) {
+	v := m.add_type
+	if v == nil {
+		return
+	}
+	return *v, true
+}
+
+// ResetType resets all changes to the "type" field.
+func (m *LabelTaggingMutation) ResetType() {
+	m._type = nil
+	m.add_type = nil
+}
+
+// SetConditions sets the "conditions" field.
+func (m *LabelTaggingMutation) SetConditions(s string) {
+	m.conditions = &s
+}
+
+// Conditions returns the value of the "conditions" field in the mutation.
+func (m *LabelTaggingMutation) Conditions() (r string, exists bool) {
+	v := m.conditions
+	if v == nil {
+		return
+	}
+	return *v, true
+}
+
+// OldConditions returns the old "conditions" field's value of the LabelTagging entity.
+// If the LabelTagging object wasn't provided to the builder, the object is fetched from the database.
+// An error is returned if the mutation operation is not UpdateOne, or the database query fails.
+func (m *LabelTaggingMutation) OldConditions(ctx context.Context) (v string, err error) {
+	if !m.op.Is(OpUpdateOne) {
+		return v, errors.New("OldConditions is only allowed on UpdateOne operations")
+	}
+	if m.id == nil || m.oldValue == nil {
+		return v, errors.New("OldConditions requires an ID field in the mutation")
+	}
+	oldValue, err := m.oldValue(ctx)
+	if err != nil {
+		return v, fmt.Errorf("querying old value for OldConditions: %w", err)
+	}
+	return oldValue.Conditions, nil
+}
+
+// ResetConditions resets all changes to the "conditions" field.
+func (m *LabelTaggingMutation) ResetConditions() {
+	m.conditions = nil
+}
+
+// SetActionLabelAdd sets the "action_label_add" field.
+func (m *LabelTaggingMutation) SetActionLabelAdd(u []uint64) {
+	m.action_label_add = &u
+	m.appendaction_label_add = nil
+}
+
+// ActionLabelAdd returns the value of the "action_label_add" field in the mutation.
+func (m *LabelTaggingMutation) ActionLabelAdd() (r []uint64, exists bool) {
+	v := m.action_label_add
+	if v == nil {
+		return
+	}
+	return *v, true
+}
+
+// OldActionLabelAdd returns the old "action_label_add" field's value of the LabelTagging entity.
+// If the LabelTagging object wasn't provided to the builder, the object is fetched from the database.
+// An error is returned if the mutation operation is not UpdateOne, or the database query fails.
+func (m *LabelTaggingMutation) OldActionLabelAdd(ctx context.Context) (v []uint64, err error) {
+	if !m.op.Is(OpUpdateOne) {
+		return v, errors.New("OldActionLabelAdd is only allowed on UpdateOne operations")
+	}
+	if m.id == nil || m.oldValue == nil {
+		return v, errors.New("OldActionLabelAdd requires an ID field in the mutation")
+	}
+	oldValue, err := m.oldValue(ctx)
+	if err != nil {
+		return v, fmt.Errorf("querying old value for OldActionLabelAdd: %w", err)
+	}
+	return oldValue.ActionLabelAdd, nil
+}
+
+// AppendActionLabelAdd adds u to the "action_label_add" field.
+func (m *LabelTaggingMutation) AppendActionLabelAdd(u []uint64) {
+	m.appendaction_label_add = append(m.appendaction_label_add, u...)
+}
+
+// AppendedActionLabelAdd returns the list of values that were appended to the "action_label_add" field in this mutation.
+func (m *LabelTaggingMutation) AppendedActionLabelAdd() ([]uint64, bool) {
+	if len(m.appendaction_label_add) == 0 {
+		return nil, false
+	}
+	return m.appendaction_label_add, true
+}
+
+// ClearActionLabelAdd clears the value of the "action_label_add" field.
+func (m *LabelTaggingMutation) ClearActionLabelAdd() {
+	m.action_label_add = nil
+	m.appendaction_label_add = nil
+	m.clearedFields[labeltagging.FieldActionLabelAdd] = struct{}{}
+}
+
+// ActionLabelAddCleared returns if the "action_label_add" field was cleared in this mutation.
+func (m *LabelTaggingMutation) ActionLabelAddCleared() bool {
+	_, ok := m.clearedFields[labeltagging.FieldActionLabelAdd]
+	return ok
+}
+
+// ResetActionLabelAdd resets all changes to the "action_label_add" field.
+func (m *LabelTaggingMutation) ResetActionLabelAdd() {
+	m.action_label_add = nil
+	m.appendaction_label_add = nil
+	delete(m.clearedFields, labeltagging.FieldActionLabelAdd)
+}
+
+// SetActionLabelDel sets the "action_label_del" field.
+func (m *LabelTaggingMutation) SetActionLabelDel(u []uint64) {
+	m.action_label_del = &u
+	m.appendaction_label_del = nil
+}
+
+// ActionLabelDel returns the value of the "action_label_del" field in the mutation.
+func (m *LabelTaggingMutation) ActionLabelDel() (r []uint64, exists bool) {
+	v := m.action_label_del
+	if v == nil {
+		return
+	}
+	return *v, true
+}
+
+// OldActionLabelDel returns the old "action_label_del" field's value of the LabelTagging entity.
+// If the LabelTagging object wasn't provided to the builder, the object is fetched from the database.
+// An error is returned if the mutation operation is not UpdateOne, or the database query fails.
+func (m *LabelTaggingMutation) OldActionLabelDel(ctx context.Context) (v []uint64, err error) {
+	if !m.op.Is(OpUpdateOne) {
+		return v, errors.New("OldActionLabelDel is only allowed on UpdateOne operations")
+	}
+	if m.id == nil || m.oldValue == nil {
+		return v, errors.New("OldActionLabelDel requires an ID field in the mutation")
+	}
+	oldValue, err := m.oldValue(ctx)
+	if err != nil {
+		return v, fmt.Errorf("querying old value for OldActionLabelDel: %w", err)
+	}
+	return oldValue.ActionLabelDel, nil
+}
+
+// AppendActionLabelDel adds u to the "action_label_del" field.
+func (m *LabelTaggingMutation) AppendActionLabelDel(u []uint64) {
+	m.appendaction_label_del = append(m.appendaction_label_del, u...)
+}
+
+// AppendedActionLabelDel returns the list of values that were appended to the "action_label_del" field in this mutation.
+func (m *LabelTaggingMutation) AppendedActionLabelDel() ([]uint64, bool) {
+	if len(m.appendaction_label_del) == 0 {
+		return nil, false
+	}
+	return m.appendaction_label_del, true
+}
+
+// ClearActionLabelDel clears the value of the "action_label_del" field.
+func (m *LabelTaggingMutation) ClearActionLabelDel() {
+	m.action_label_del = nil
+	m.appendaction_label_del = nil
+	m.clearedFields[labeltagging.FieldActionLabelDel] = struct{}{}
+}
+
+// ActionLabelDelCleared returns if the "action_label_del" field was cleared in this mutation.
+func (m *LabelTaggingMutation) ActionLabelDelCleared() bool {
+	_, ok := m.clearedFields[labeltagging.FieldActionLabelDel]
+	return ok
+}
+
+// ResetActionLabelDel resets all changes to the "action_label_del" field.
+func (m *LabelTaggingMutation) ResetActionLabelDel() {
+	m.action_label_del = nil
+	m.appendaction_label_del = nil
+	delete(m.clearedFields, labeltagging.FieldActionLabelDel)
+}
+
+// Where appends a list predicates to the LabelTaggingMutation builder.
+func (m *LabelTaggingMutation) Where(ps ...predicate.LabelTagging) {
+	m.predicates = append(m.predicates, ps...)
+}
+
+// WhereP appends storage-level predicates to the LabelTaggingMutation builder. Using this method,
+// users can use type-assertion to append predicates that do not depend on any generated package.
+func (m *LabelTaggingMutation) WhereP(ps ...func(*sql.Selector)) {
+	p := make([]predicate.LabelTagging, len(ps))
+	for i := range ps {
+		p[i] = ps[i]
+	}
+	m.Where(p...)
+}
+
+// Op returns the operation name.
+func (m *LabelTaggingMutation) Op() Op {
+	return m.op
+}
+
+// SetOp allows setting the mutation operation.
+func (m *LabelTaggingMutation) SetOp(op Op) {
+	m.op = op
+}
+
+// Type returns the node type of this mutation (LabelTagging).
+func (m *LabelTaggingMutation) Type() string {
+	return m.typ
+}
+
+// Fields returns all fields that were changed during this mutation. Note that in
+// order to get all numeric fields that were incremented/decremented, call
+// AddedFields().
+func (m *LabelTaggingMutation) Fields() []string {
+	fields := make([]string, 0, 9)
+	if m.created_at != nil {
+		fields = append(fields, labeltagging.FieldCreatedAt)
+	}
+	if m.updated_at != nil {
+		fields = append(fields, labeltagging.FieldUpdatedAt)
+	}
+	if m.status != nil {
+		fields = append(fields, labeltagging.FieldStatus)
+	}
+	if m.deleted_at != nil {
+		fields = append(fields, labeltagging.FieldDeletedAt)
+	}
+	if m.organization_id != nil {
+		fields = append(fields, labeltagging.FieldOrganizationID)
+	}
+	if m._type != nil {
+		fields = append(fields, labeltagging.FieldType)
+	}
+	if m.conditions != nil {
+		fields = append(fields, labeltagging.FieldConditions)
+	}
+	if m.action_label_add != nil {
+		fields = append(fields, labeltagging.FieldActionLabelAdd)
+	}
+	if m.action_label_del != nil {
+		fields = append(fields, labeltagging.FieldActionLabelDel)
+	}
+	return fields
+}
+
+// Field returns the value of a field with the given name. The second boolean
+// return value indicates that this field was not set, or was not defined in the
+// schema.
+func (m *LabelTaggingMutation) Field(name string) (ent.Value, bool) {
+	switch name {
+	case labeltagging.FieldCreatedAt:
+		return m.CreatedAt()
+	case labeltagging.FieldUpdatedAt:
+		return m.UpdatedAt()
+	case labeltagging.FieldStatus:
+		return m.Status()
+	case labeltagging.FieldDeletedAt:
+		return m.DeletedAt()
+	case labeltagging.FieldOrganizationID:
+		return m.OrganizationID()
+	case labeltagging.FieldType:
+		return m.GetType()
+	case labeltagging.FieldConditions:
+		return m.Conditions()
+	case labeltagging.FieldActionLabelAdd:
+		return m.ActionLabelAdd()
+	case labeltagging.FieldActionLabelDel:
+		return m.ActionLabelDel()
+	}
+	return nil, false
+}
+
+// OldField returns the old value of the field from the database. An error is
+// returned if the mutation operation is not UpdateOne, or the query to the
+// database failed.
+func (m *LabelTaggingMutation) OldField(ctx context.Context, name string) (ent.Value, error) {
+	switch name {
+	case labeltagging.FieldCreatedAt:
+		return m.OldCreatedAt(ctx)
+	case labeltagging.FieldUpdatedAt:
+		return m.OldUpdatedAt(ctx)
+	case labeltagging.FieldStatus:
+		return m.OldStatus(ctx)
+	case labeltagging.FieldDeletedAt:
+		return m.OldDeletedAt(ctx)
+	case labeltagging.FieldOrganizationID:
+		return m.OldOrganizationID(ctx)
+	case labeltagging.FieldType:
+		return m.OldType(ctx)
+	case labeltagging.FieldConditions:
+		return m.OldConditions(ctx)
+	case labeltagging.FieldActionLabelAdd:
+		return m.OldActionLabelAdd(ctx)
+	case labeltagging.FieldActionLabelDel:
+		return m.OldActionLabelDel(ctx)
+	}
+	return nil, fmt.Errorf("unknown LabelTagging field %s", name)
+}
+
+// SetField sets the value of a field with the given name. It returns an error if
+// the field is not defined in the schema, or if the type mismatched the field
+// type.
+func (m *LabelTaggingMutation) SetField(name string, value ent.Value) error {
+	switch name {
+	case labeltagging.FieldCreatedAt:
+		v, ok := value.(time.Time)
+		if !ok {
+			return fmt.Errorf("unexpected type %T for field %s", value, name)
+		}
+		m.SetCreatedAt(v)
+		return nil
+	case labeltagging.FieldUpdatedAt:
+		v, ok := value.(time.Time)
+		if !ok {
+			return fmt.Errorf("unexpected type %T for field %s", value, name)
+		}
+		m.SetUpdatedAt(v)
+		return nil
+	case labeltagging.FieldStatus:
+		v, ok := value.(uint8)
+		if !ok {
+			return fmt.Errorf("unexpected type %T for field %s", value, name)
+		}
+		m.SetStatus(v)
+		return nil
+	case labeltagging.FieldDeletedAt:
+		v, ok := value.(time.Time)
+		if !ok {
+			return fmt.Errorf("unexpected type %T for field %s", value, name)
+		}
+		m.SetDeletedAt(v)
+		return nil
+	case labeltagging.FieldOrganizationID:
+		v, ok := value.(uint64)
+		if !ok {
+			return fmt.Errorf("unexpected type %T for field %s", value, name)
+		}
+		m.SetOrganizationID(v)
+		return nil
+	case labeltagging.FieldType:
+		v, ok := value.(int)
+		if !ok {
+			return fmt.Errorf("unexpected type %T for field %s", value, name)
+		}
+		m.SetType(v)
+		return nil
+	case labeltagging.FieldConditions:
+		v, ok := value.(string)
+		if !ok {
+			return fmt.Errorf("unexpected type %T for field %s", value, name)
+		}
+		m.SetConditions(v)
+		return nil
+	case labeltagging.FieldActionLabelAdd:
+		v, ok := value.([]uint64)
+		if !ok {
+			return fmt.Errorf("unexpected type %T for field %s", value, name)
+		}
+		m.SetActionLabelAdd(v)
+		return nil
+	case labeltagging.FieldActionLabelDel:
+		v, ok := value.([]uint64)
+		if !ok {
+			return fmt.Errorf("unexpected type %T for field %s", value, name)
+		}
+		m.SetActionLabelDel(v)
+		return nil
+	}
+	return fmt.Errorf("unknown LabelTagging field %s", name)
+}
+
+// AddedFields returns all numeric fields that were incremented/decremented during
+// this mutation.
+func (m *LabelTaggingMutation) AddedFields() []string {
+	var fields []string
+	if m.addstatus != nil {
+		fields = append(fields, labeltagging.FieldStatus)
+	}
+	if m.addorganization_id != nil {
+		fields = append(fields, labeltagging.FieldOrganizationID)
+	}
+	if m.add_type != nil {
+		fields = append(fields, labeltagging.FieldType)
+	}
+	return fields
+}
+
+// AddedField returns the numeric value that was incremented/decremented on a field
+// with the given name. The second boolean return value indicates that this field
+// was not set, or was not defined in the schema.
+func (m *LabelTaggingMutation) AddedField(name string) (ent.Value, bool) {
+	switch name {
+	case labeltagging.FieldStatus:
+		return m.AddedStatus()
+	case labeltagging.FieldOrganizationID:
+		return m.AddedOrganizationID()
+	case labeltagging.FieldType:
+		return m.AddedType()
+	}
+	return nil, false
+}
+
+// AddField adds the value to the field with the given name. It returns an error if
+// the field is not defined in the schema, or if the type mismatched the field
+// type.
+func (m *LabelTaggingMutation) AddField(name string, value ent.Value) error {
+	switch name {
+	case labeltagging.FieldStatus:
+		v, ok := value.(int8)
+		if !ok {
+			return fmt.Errorf("unexpected type %T for field %s", value, name)
+		}
+		m.AddStatus(v)
+		return nil
+	case labeltagging.FieldOrganizationID:
+		v, ok := value.(int64)
+		if !ok {
+			return fmt.Errorf("unexpected type %T for field %s", value, name)
+		}
+		m.AddOrganizationID(v)
+		return nil
+	case labeltagging.FieldType:
+		v, ok := value.(int)
+		if !ok {
+			return fmt.Errorf("unexpected type %T for field %s", value, name)
+		}
+		m.AddType(v)
+		return nil
+	}
+	return fmt.Errorf("unknown LabelTagging numeric field %s", name)
+}
+
+// ClearedFields returns all nullable fields that were cleared during this
+// mutation.
+func (m *LabelTaggingMutation) ClearedFields() []string {
+	var fields []string
+	if m.FieldCleared(labeltagging.FieldStatus) {
+		fields = append(fields, labeltagging.FieldStatus)
+	}
+	if m.FieldCleared(labeltagging.FieldDeletedAt) {
+		fields = append(fields, labeltagging.FieldDeletedAt)
+	}
+	if m.FieldCleared(labeltagging.FieldActionLabelAdd) {
+		fields = append(fields, labeltagging.FieldActionLabelAdd)
+	}
+	if m.FieldCleared(labeltagging.FieldActionLabelDel) {
+		fields = append(fields, labeltagging.FieldActionLabelDel)
+	}
+	return fields
+}
+
+// FieldCleared returns a boolean indicating if a field with the given name was
+// cleared in this mutation.
+func (m *LabelTaggingMutation) FieldCleared(name string) bool {
+	_, ok := m.clearedFields[name]
+	return ok
+}
+
+// ClearField clears the value of the field with the given name. It returns an
+// error if the field is not defined in the schema.
+func (m *LabelTaggingMutation) ClearField(name string) error {
+	switch name {
+	case labeltagging.FieldStatus:
+		m.ClearStatus()
+		return nil
+	case labeltagging.FieldDeletedAt:
+		m.ClearDeletedAt()
+		return nil
+	case labeltagging.FieldActionLabelAdd:
+		m.ClearActionLabelAdd()
+		return nil
+	case labeltagging.FieldActionLabelDel:
+		m.ClearActionLabelDel()
+		return nil
+	}
+	return fmt.Errorf("unknown LabelTagging nullable field %s", name)
+}
+
+// ResetField resets all changes in the mutation for the field with the given name.
+// It returns an error if the field is not defined in the schema.
+func (m *LabelTaggingMutation) ResetField(name string) error {
+	switch name {
+	case labeltagging.FieldCreatedAt:
+		m.ResetCreatedAt()
+		return nil
+	case labeltagging.FieldUpdatedAt:
+		m.ResetUpdatedAt()
+		return nil
+	case labeltagging.FieldStatus:
+		m.ResetStatus()
+		return nil
+	case labeltagging.FieldDeletedAt:
+		m.ResetDeletedAt()
+		return nil
+	case labeltagging.FieldOrganizationID:
+		m.ResetOrganizationID()
+		return nil
+	case labeltagging.FieldType:
+		m.ResetType()
+		return nil
+	case labeltagging.FieldConditions:
+		m.ResetConditions()
+		return nil
+	case labeltagging.FieldActionLabelAdd:
+		m.ResetActionLabelAdd()
+		return nil
+	case labeltagging.FieldActionLabelDel:
+		m.ResetActionLabelDel()
+		return nil
+	}
+	return fmt.Errorf("unknown LabelTagging field %s", name)
+}
+
+// AddedEdges returns all edge names that were set/added in this mutation.
+func (m *LabelTaggingMutation) AddedEdges() []string {
+	edges := make([]string, 0, 0)
+	return edges
+}
+
+// AddedIDs returns all IDs (to other nodes) that were added for the given edge
+// name in this mutation.
+func (m *LabelTaggingMutation) AddedIDs(name string) []ent.Value {
+	return nil
+}
+
+// RemovedEdges returns all edge names that were removed in this mutation.
+func (m *LabelTaggingMutation) RemovedEdges() []string {
+	edges := make([]string, 0, 0)
+	return edges
+}
+
+// RemovedIDs returns all IDs (to other nodes) that were removed for the edge with
+// the given name in this mutation.
+func (m *LabelTaggingMutation) RemovedIDs(name string) []ent.Value {
+	return nil
+}
+
+// ClearedEdges returns all edge names that were cleared in this mutation.
+func (m *LabelTaggingMutation) ClearedEdges() []string {
+	edges := make([]string, 0, 0)
+	return edges
+}
+
+// EdgeCleared returns a boolean which indicates if the edge with the given name
+// was cleared in this mutation.
+func (m *LabelTaggingMutation) EdgeCleared(name string) bool {
+	return false
+}
+
+// ClearEdge clears the value of the edge with the given name. It returns an error
+// if that edge is not defined in the schema.
+func (m *LabelTaggingMutation) ClearEdge(name string) error {
+	return fmt.Errorf("unknown LabelTagging unique edge %s", name)
+}
+
+// ResetEdge resets all changes to the edge with the given name in this mutation.
+// It returns an error if the edge is not defined in the schema.
+func (m *LabelTaggingMutation) ResetEdge(name string) error {
+	return fmt.Errorf("unknown LabelTagging edge %s", name)
+}
+
 // MessageMutation represents an operation that mutates the Message nodes in the graph.
 type MessageMutation struct {
 	config

+ 82 - 0
ent/pagination.go

@@ -20,6 +20,7 @@ import (
 	"wechat-api/ent/employeeconfig"
 	"wechat-api/ent/label"
 	"wechat-api/ent/labelrelationship"
+	"wechat-api/ent/labeltagging"
 	"wechat-api/ent/message"
 	"wechat-api/ent/messagerecords"
 	"wechat-api/ent/msg"
@@ -1305,6 +1306,87 @@ func (lr *LabelRelationshipQuery) Page(
 	return ret, nil
 }
 
+type LabelTaggingPager struct {
+	Order  labeltagging.OrderOption
+	Filter func(*LabelTaggingQuery) (*LabelTaggingQuery, error)
+}
+
+// LabelTaggingPaginateOption enables pagination customization.
+type LabelTaggingPaginateOption func(*LabelTaggingPager)
+
+// DefaultLabelTaggingOrder is the default ordering of LabelTagging.
+var DefaultLabelTaggingOrder = Desc(labeltagging.FieldID)
+
+func newLabelTaggingPager(opts []LabelTaggingPaginateOption) (*LabelTaggingPager, error) {
+	pager := &LabelTaggingPager{}
+	for _, opt := range opts {
+		opt(pager)
+	}
+	if pager.Order == nil {
+		pager.Order = DefaultLabelTaggingOrder
+	}
+	return pager, nil
+}
+
+func (p *LabelTaggingPager) ApplyFilter(query *LabelTaggingQuery) (*LabelTaggingQuery, error) {
+	if p.Filter != nil {
+		return p.Filter(query)
+	}
+	return query, nil
+}
+
+// LabelTaggingPageList is LabelTagging PageList result.
+type LabelTaggingPageList struct {
+	List        []*LabelTagging `json:"list"`
+	PageDetails *PageDetails    `json:"pageDetails"`
+}
+
+func (lt *LabelTaggingQuery) Page(
+	ctx context.Context, pageNum uint64, pageSize uint64, opts ...LabelTaggingPaginateOption,
+) (*LabelTaggingPageList, error) {
+
+	pager, err := newLabelTaggingPager(opts)
+	if err != nil {
+		return nil, err
+	}
+
+	if lt, err = pager.ApplyFilter(lt); err != nil {
+		return nil, err
+	}
+
+	ret := &LabelTaggingPageList{}
+
+	ret.PageDetails = &PageDetails{
+		Page: pageNum,
+		Size: pageSize,
+	}
+
+	query := lt.Clone()
+	query.ctx.Fields = nil
+	count, err := query.Count(ctx)
+
+	if err != nil {
+		return nil, err
+	}
+
+	ret.PageDetails.Total = uint64(count)
+
+	if pager.Order != nil {
+		lt = lt.Order(pager.Order)
+	} else {
+		lt = lt.Order(DefaultLabelTaggingOrder)
+	}
+
+	lt = lt.Offset(int((pageNum - 1) * pageSize)).Limit(int(pageSize))
+	list, err := lt.All(ctx)
+	if err != nil {
+		return nil, err
+	}
+	ret.List = list
+
+	return ret, nil
+}
+
 type MessagePager struct {
 	Order  message.OrderOption
 	Filter func(*MessageQuery) (*MessageQuery, error)

+ 3 - 0
ent/predicate/predicate.go

@@ -51,6 +51,9 @@ type Label func(*sql.Selector)
 // LabelRelationship is the predicate function for labelrelationship builders.
 type LabelRelationship func(*sql.Selector)
 
+// LabelTagging is the predicate function for labeltagging builders.
+type LabelTagging func(*sql.Selector)
+
 // Message is the predicate function for message builders.
 type Message func(*sql.Selector)
 

+ 38 - 4
ent/runtime/runtime.go

@@ -19,6 +19,7 @@ import (
 	"wechat-api/ent/employeeconfig"
 	"wechat-api/ent/label"
 	"wechat-api/ent/labelrelationship"
+	"wechat-api/ent/labeltagging"
 	"wechat-api/ent/message"
 	"wechat-api/ent/messagerecords"
 	"wechat-api/ent/msg"
@@ -668,10 +669,6 @@ func init() {
 	// label.DefaultOrganizationID holds the default value on creation for the organization_id field.
 	label.DefaultOrganizationID = labelDescOrganizationID.Default.(uint64)
 	labelrelationshipMixin := schema.LabelRelationship{}.Mixin()
-	labelrelationshipMixinHooks2 := labelrelationshipMixin[2].Hooks()
-	labelrelationship.Hooks[0] = labelrelationshipMixinHooks2[0]
-	labelrelationshipMixinInters2 := labelrelationshipMixin[2].Interceptors()
-	labelrelationship.Interceptors[0] = labelrelationshipMixinInters2[0]
 	labelrelationshipMixinFields0 := labelrelationshipMixin[0].Fields()
 	_ = labelrelationshipMixinFields0
 	labelrelationshipMixinFields1 := labelrelationshipMixin[1].Fields()
@@ -704,6 +701,43 @@ func init() {
 	labelrelationshipDescOrganizationID := labelrelationshipFields[2].Descriptor()
 	// labelrelationship.DefaultOrganizationID holds the default value on creation for the organization_id field.
 	labelrelationship.DefaultOrganizationID = labelrelationshipDescOrganizationID.Default.(uint64)
+	labeltaggingMixin := schema.LabelTagging{}.Mixin()
+	labeltaggingMixinHooks2 := labeltaggingMixin[2].Hooks()
+	labeltagging.Hooks[0] = labeltaggingMixinHooks2[0]
+	labeltaggingMixinInters2 := labeltaggingMixin[2].Interceptors()
+	labeltagging.Interceptors[0] = labeltaggingMixinInters2[0]
+	labeltaggingMixinFields0 := labeltaggingMixin[0].Fields()
+	_ = labeltaggingMixinFields0
+	labeltaggingMixinFields1 := labeltaggingMixin[1].Fields()
+	_ = labeltaggingMixinFields1
+	labeltaggingFields := schema.LabelTagging{}.Fields()
+	_ = labeltaggingFields
+	// labeltaggingDescCreatedAt is the schema descriptor for created_at field.
+	labeltaggingDescCreatedAt := labeltaggingMixinFields0[1].Descriptor()
+	// labeltagging.DefaultCreatedAt holds the default value on creation for the created_at field.
+	labeltagging.DefaultCreatedAt = labeltaggingDescCreatedAt.Default.(func() time.Time)
+	// labeltaggingDescUpdatedAt is the schema descriptor for updated_at field.
+	labeltaggingDescUpdatedAt := labeltaggingMixinFields0[2].Descriptor()
+	// labeltagging.DefaultUpdatedAt holds the default value on creation for the updated_at field.
+	labeltagging.DefaultUpdatedAt = labeltaggingDescUpdatedAt.Default.(func() time.Time)
+	// labeltagging.UpdateDefaultUpdatedAt holds the default value on update for the updated_at field.
+	labeltagging.UpdateDefaultUpdatedAt = labeltaggingDescUpdatedAt.UpdateDefault.(func() time.Time)
+	// labeltaggingDescStatus is the schema descriptor for status field.
+	labeltaggingDescStatus := labeltaggingMixinFields1[0].Descriptor()
+	// labeltagging.DefaultStatus holds the default value on creation for the status field.
+	labeltagging.DefaultStatus = labeltaggingDescStatus.Default.(uint8)
+	// labeltaggingDescOrganizationID is the schema descriptor for organization_id field.
+	labeltaggingDescOrganizationID := labeltaggingFields[0].Descriptor()
+	// labeltagging.DefaultOrganizationID holds the default value on creation for the organization_id field.
+	labeltagging.DefaultOrganizationID = labeltaggingDescOrganizationID.Default.(uint64)
+	// labeltaggingDescType is the schema descriptor for type field.
+	labeltaggingDescType := labeltaggingFields[1].Descriptor()
+	// labeltagging.DefaultType holds the default value on creation for the type field.
+	labeltagging.DefaultType = labeltaggingDescType.Default.(int)
+	// labeltaggingDescConditions is the schema descriptor for conditions field.
+	labeltaggingDescConditions := labeltaggingFields[2].Descriptor()
+	// labeltagging.DefaultConditions holds the default value on creation for the conditions field.
+	labeltagging.DefaultConditions = labeltaggingDescConditions.Default.(string)
 	messageFields := schema.Message{}.Fields()
 	_ = messageFields
 	// messageDescWxWxid is the schema descriptor for wx_wxid field.

+ 0 - 3
ent/schema/label_relationship.go

@@ -1,8 +1,6 @@
 package schema
 
 import (
-	"wechat-api/ent/schema/localmixin"
-
 	"entgo.io/ent"
 	"entgo.io/ent/dialect/entsql"
 	"entgo.io/ent/schema"
@@ -34,7 +32,6 @@ func (LabelRelationship) Mixin() []ent.Mixin {
 	return []ent.Mixin{
 		mixins.IDMixin{},
 		mixins.StatusMixin{},
-		localmixin.SoftDeleteMixin{},
 	}
 }
 

+ 57 - 0
ent/schema/label_tagging.go

@@ -0,0 +1,57 @@
+package schema
+
+import (
+	"entgo.io/ent"
+	"entgo.io/ent/dialect/entsql"
+	"entgo.io/ent/schema"
+	"entgo.io/ent/schema/field"
+	"github.com/suyuan32/simple-admin-common/orm/ent/mixins"
+	"wechat-api/ent/schema/localmixin"
+)
+
+type LabelTagging struct {
+	ent.Schema
+}
+
+func (LabelTagging) Fields() []ent.Field {
+	return []ent.Field{
+		field.Uint64("organization_id").Default(1).
+			Comment("机构 ID").
+			Annotations(entsql.WithComments(true)),
+		field.Int("type").Default(1).
+			Annotations(entsql.WithComments(true)).
+			Comment("标签类型:1好友,2群组,3公众号,4企业微信联系人"),
+		field.String("conditions").Default("").
+			Annotations(entsql.WithComments(true)).
+			Comment("关键词"),
+		field.JSON("action_label_add", []uint64{}).Optional().
+			Annotations(entsql.WithComments(true)).
+			Comment("命中后需要打的标签"),
+		field.JSON("action_label_del", []uint64{}).Optional().
+			Annotations(entsql.WithComments(true)).
+			Comment("命中后需要移除的标签"),
+	}
+}
+
+func (LabelTagging) Mixin() []ent.Mixin {
+	return []ent.Mixin{
+		mixins.IDMixin{},
+		mixins.StatusMixin{},
+		localmixin.SoftDeleteMixin{},
+	}
+}
+
+func (LabelTagging) Indexes() []ent.Index {
+	return []ent.Index{}
+}
+
+func (LabelTagging) Edges() []ent.Edge {
+	return nil
+}
+
+func (LabelTagging) Annotations() []schema.Annotation {
+	return []schema.Annotation{
+		entsql.WithComments(true),
+		entsql.Annotation{Table: "label_tagging"},
+	}
+}

+ 192 - 24
ent/set_not_nil.go

@@ -3488,30 +3488,6 @@ func (lr *LabelRelationshipCreate) SetNotNilStatus(value *uint8) *LabelRelations
 }
 
 // set field if value's pointer is not nil.
-func (lr *LabelRelationshipUpdate) SetNotNilDeletedAt(value *time.Time) *LabelRelationshipUpdate {
-	if value != nil {
-		return lr.SetDeletedAt(*value)
-	}
-	return lr
-}
-
-// set field if value's pointer is not nil.
-func (lr *LabelRelationshipUpdateOne) SetNotNilDeletedAt(value *time.Time) *LabelRelationshipUpdateOne {
-	if value != nil {
-		return lr.SetDeletedAt(*value)
-	}
-	return lr
-}
-
-// set field if value's pointer is not nil.
-func (lr *LabelRelationshipCreate) SetNotNilDeletedAt(value *time.Time) *LabelRelationshipCreate {
-	if value != nil {
-		return lr.SetDeletedAt(*value)
-	}
-	return lr
-}
-
-// set field if value's pointer is not nil.
 func (lr *LabelRelationshipUpdate) SetNotNilLabelID(value *uint64) *LabelRelationshipUpdate {
 	if value != nil {
 		return lr.SetLabelID(*value)
@@ -3584,6 +3560,198 @@ func (lr *LabelRelationshipCreate) SetNotNilOrganizationID(value *uint64) *Label
 }
 
 // set field if value's pointer is not nil.
+func (lt *LabelTaggingUpdate) SetNotNilUpdatedAt(value *time.Time) *LabelTaggingUpdate {
+	if value != nil {
+		return lt.SetUpdatedAt(*value)
+	}
+	return lt
+}
+
+// set field if value's pointer is not nil.
+func (lt *LabelTaggingUpdateOne) SetNotNilUpdatedAt(value *time.Time) *LabelTaggingUpdateOne {
+	if value != nil {
+		return lt.SetUpdatedAt(*value)
+	}
+	return lt
+}
+
+// set field if value's pointer is not nil.
+func (lt *LabelTaggingCreate) SetNotNilUpdatedAt(value *time.Time) *LabelTaggingCreate {
+	if value != nil {
+		return lt.SetUpdatedAt(*value)
+	}
+	return lt
+}
+
+// set field if value's pointer is not nil.
+func (lt *LabelTaggingUpdate) SetNotNilStatus(value *uint8) *LabelTaggingUpdate {
+	if value != nil {
+		return lt.SetStatus(*value)
+	}
+	return lt
+}
+
+// set field if value's pointer is not nil.
+func (lt *LabelTaggingUpdateOne) SetNotNilStatus(value *uint8) *LabelTaggingUpdateOne {
+	if value != nil {
+		return lt.SetStatus(*value)
+	}
+	return lt
+}
+
+// set field if value's pointer is not nil.
+func (lt *LabelTaggingCreate) SetNotNilStatus(value *uint8) *LabelTaggingCreate {
+	if value != nil {
+		return lt.SetStatus(*value)
+	}
+	return lt
+}
+
+// set field if value's pointer is not nil.
+func (lt *LabelTaggingUpdate) SetNotNilDeletedAt(value *time.Time) *LabelTaggingUpdate {
+	if value != nil {
+		return lt.SetDeletedAt(*value)
+	}
+	return lt
+}
+
+// set field if value's pointer is not nil.
+func (lt *LabelTaggingUpdateOne) SetNotNilDeletedAt(value *time.Time) *LabelTaggingUpdateOne {
+	if value != nil {
+		return lt.SetDeletedAt(*value)
+	}
+	return lt
+}
+
+// set field if value's pointer is not nil.
+func (lt *LabelTaggingCreate) SetNotNilDeletedAt(value *time.Time) *LabelTaggingCreate {
+	if value != nil {
+		return lt.SetDeletedAt(*value)
+	}
+	return lt
+}
+
+// set field if value's pointer is not nil.
+func (lt *LabelTaggingUpdate) SetNotNilOrganizationID(value *uint64) *LabelTaggingUpdate {
+	if value != nil {
+		return lt.SetOrganizationID(*value)
+	}
+	return lt
+}
+
+// set field if value's pointer is not nil.
+func (lt *LabelTaggingUpdateOne) SetNotNilOrganizationID(value *uint64) *LabelTaggingUpdateOne {
+	if value != nil {
+		return lt.SetOrganizationID(*value)
+	}
+	return lt
+}
+
+// set field if value's pointer is not nil.
+func (lt *LabelTaggingCreate) SetNotNilOrganizationID(value *uint64) *LabelTaggingCreate {
+	if value != nil {
+		return lt.SetOrganizationID(*value)
+	}
+	return lt
+}
+
+// set field if value's pointer is not nil.
+func (lt *LabelTaggingUpdate) SetNotNilType(value *int) *LabelTaggingUpdate {
+	if value != nil {
+		return lt.SetType(*value)
+	}
+	return lt
+}
+
+// set field if value's pointer is not nil.
+func (lt *LabelTaggingUpdateOne) SetNotNilType(value *int) *LabelTaggingUpdateOne {
+	if value != nil {
+		return lt.SetType(*value)
+	}
+	return lt
+}
+
+// set field if value's pointer is not nil.
+func (lt *LabelTaggingCreate) SetNotNilType(value *int) *LabelTaggingCreate {
+	if value != nil {
+		return lt.SetType(*value)
+	}
+	return lt
+}
+
+// set field if value's pointer is not nil.
+func (lt *LabelTaggingUpdate) SetNotNilConditions(value *string) *LabelTaggingUpdate {
+	if value != nil {
+		return lt.SetConditions(*value)
+	}
+	return lt
+}
+
+// set field if value's pointer is not nil.
+func (lt *LabelTaggingUpdateOne) SetNotNilConditions(value *string) *LabelTaggingUpdateOne {
+	if value != nil {
+		return lt.SetConditions(*value)
+	}
+	return lt
+}
+
+// set field if value's pointer is not nil.
+func (lt *LabelTaggingCreate) SetNotNilConditions(value *string) *LabelTaggingCreate {
+	if value != nil {
+		return lt.SetConditions(*value)
+	}
+	return lt
+}
+
+// set field if value's pointer is not nil.
+func (lt *LabelTaggingUpdate) SetNotNilActionLabelAdd(value []uint64) *LabelTaggingUpdate {
+	if value != nil {
+		return lt.SetActionLabelAdd(value)
+	}
+	return lt
+}
+
+// set field if value's pointer is not nil.
+func (lt *LabelTaggingUpdateOne) SetNotNilActionLabelAdd(value []uint64) *LabelTaggingUpdateOne {
+	if value != nil {
+		return lt.SetActionLabelAdd(value)
+	}
+	return lt
+}
+
+// set field if value's pointer is not nil.
+func (lt *LabelTaggingCreate) SetNotNilActionLabelAdd(value []uint64) *LabelTaggingCreate {
+	if value != nil {
+		return lt.SetActionLabelAdd(value)
+	}
+	return lt
+}
+
+// set field if value's pointer is not nil.
+func (lt *LabelTaggingUpdate) SetNotNilActionLabelDel(value []uint64) *LabelTaggingUpdate {
+	if value != nil {
+		return lt.SetActionLabelDel(value)
+	}
+	return lt
+}
+
+// set field if value's pointer is not nil.
+func (lt *LabelTaggingUpdateOne) SetNotNilActionLabelDel(value []uint64) *LabelTaggingUpdateOne {
+	if value != nil {
+		return lt.SetActionLabelDel(value)
+	}
+	return lt
+}
+
+// set field if value's pointer is not nil.
+func (lt *LabelTaggingCreate) SetNotNilActionLabelDel(value []uint64) *LabelTaggingCreate {
+	if value != nil {
+		return lt.SetActionLabelDel(value)
+	}
+	return lt
+}
+
+// set field if value's pointer is not nil.
 func (m *MessageUpdate) SetNotNilWxWxid(value *string) *MessageUpdate {
 	if value != nil {
 		return m.SetWxWxid(*value)

+ 3 - 0
ent/tx.go

@@ -44,6 +44,8 @@ type Tx struct {
 	Label *LabelClient
 	// LabelRelationship is the client for interacting with the LabelRelationship builders.
 	LabelRelationship *LabelRelationshipClient
+	// LabelTagging is the client for interacting with the LabelTagging builders.
+	LabelTagging *LabelTaggingClient
 	// Message is the client for interacting with the Message builders.
 	Message *MessageClient
 	// MessageRecords is the client for interacting with the MessageRecords builders.
@@ -234,6 +236,7 @@ func (tx *Tx) init() {
 	tx.EmployeeConfig = NewEmployeeConfigClient(tx.config)
 	tx.Label = NewLabelClient(tx.config)
 	tx.LabelRelationship = NewLabelRelationshipClient(tx.config)
+	tx.LabelTagging = NewLabelTaggingClient(tx.config)
 	tx.Message = NewMessageClient(tx.config)
 	tx.MessageRecords = NewMessageRecordsClient(tx.config)
 	tx.Msg = NewMsgClient(tx.config)

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

@@ -0,0 +1,44 @@
+package Wx
+
+import (
+	"net/http"
+
+	"github.com/zeromicro/go-zero/rest/httpx"
+
+	"wechat-api/internal/logic/Wx"
+	"wechat-api/internal/svc"
+	"wechat-api/internal/types"
+)
+
+// swagger:route post /wx/selectList Wx GetSelectWxList
+//
+// Get wx list | 获取Wx列表
+//
+// Get wx list | 获取Wx列表
+//
+// Parameters:
+//  + name: body
+//    require: true
+//    in: body
+//    type: WxSelectListReq
+//
+// Responses:
+//  200: WxSelectListResp
+
+func GetSelectWxListHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
+	return func(w http.ResponseWriter, r *http.Request) {
+		var req types.WxSelectListReq
+		if err := httpx.Parse(r, &req, true); err != nil {
+			httpx.ErrorCtx(r.Context(), w, err)
+			return
+		}
+
+		l := Wx.NewGetSelectWxListLogic(r.Context(), svcCtx)
+		resp, err := l.GetSelectWxList(&req)
+		if err != nil {
+			httpx.ErrorCtx(r.Context(), w, err)
+		} else {
+			httpx.OkJsonCtx(r.Context(), w, resp)
+		}
+	}
+}

+ 44 - 0
internal/handler/label_tagging/create_label_tagging_handler.go

@@ -0,0 +1,44 @@
+package label_tagging
+
+import (
+	"net/http"
+
+	"github.com/zeromicro/go-zero/rest/httpx"
+
+	"wechat-api/internal/logic/label_tagging"
+	"wechat-api/internal/svc"
+	"wechat-api/internal/types"
+)
+
+// swagger:route post /label_tagging/create label_tagging CreateLabelTagging
+//
+// Create label tagging information | 创建LabelTagging信息
+//
+// Create label tagging information | 创建LabelTagging信息
+//
+// Parameters:
+//  + name: body
+//    require: true
+//    in: body
+//    type: LabelTaggingInfo
+//
+// Responses:
+//  200: BaseMsgResp
+
+func CreateLabelTaggingHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
+	return func(w http.ResponseWriter, r *http.Request) {
+		var req types.LabelTaggingInfo
+		if err := httpx.Parse(r, &req, true); err != nil {
+			httpx.ErrorCtx(r.Context(), w, err)
+			return
+		}
+
+		l := label_tagging.NewCreateLabelTaggingLogic(r.Context(), svcCtx)
+		resp, err := l.CreateLabelTagging(&req)
+		if err != nil {
+			httpx.ErrorCtx(r.Context(), w, err)
+		} else {
+			httpx.OkJsonCtx(r.Context(), w, resp)
+		}
+	}
+}

+ 44 - 0
internal/handler/label_tagging/delete_label_tagging_handler.go

@@ -0,0 +1,44 @@
+package label_tagging
+
+import (
+	"net/http"
+
+	"github.com/zeromicro/go-zero/rest/httpx"
+
+	"wechat-api/internal/logic/label_tagging"
+	"wechat-api/internal/svc"
+	"wechat-api/internal/types"
+)
+
+// swagger:route post /label_tagging/delete label_tagging DeleteLabelTagging
+//
+// Delete label tagging information | 删除LabelTagging信息
+//
+// Delete label tagging information | 删除LabelTagging信息
+//
+// Parameters:
+//  + name: body
+//    require: true
+//    in: body
+//    type: IDReq
+//
+// Responses:
+//  200: BaseMsgResp
+
+func DeleteLabelTaggingHandler(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 := label_tagging.NewDeleteLabelTaggingLogic(r.Context(), svcCtx)
+		resp, err := l.DeleteLabelTagging(&req)
+		if err != nil {
+			httpx.ErrorCtx(r.Context(), w, err)
+		} else {
+			httpx.OkJsonCtx(r.Context(), w, resp)
+		}
+	}
+}

+ 44 - 0
internal/handler/label_tagging/get_label_tagging_by_id_handler.go

@@ -0,0 +1,44 @@
+package label_tagging
+
+import (
+	"net/http"
+
+	"github.com/zeromicro/go-zero/rest/httpx"
+
+	"wechat-api/internal/logic/label_tagging"
+	"wechat-api/internal/svc"
+	"wechat-api/internal/types"
+)
+
+// swagger:route post /label_tagging label_tagging GetLabelTaggingById
+//
+// Get label tagging by ID | 通过ID获取LabelTagging信息
+//
+// Get label tagging by ID | 通过ID获取LabelTagging信息
+//
+// Parameters:
+//  + name: body
+//    require: true
+//    in: body
+//    type: IDReq
+//
+// Responses:
+//  200: LabelTaggingInfoResp
+
+func GetLabelTaggingByIdHandler(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 := label_tagging.NewGetLabelTaggingByIdLogic(r.Context(), svcCtx)
+		resp, err := l.GetLabelTaggingById(&req)
+		if err != nil {
+			httpx.ErrorCtx(r.Context(), w, err)
+		} else {
+			httpx.OkJsonCtx(r.Context(), w, resp)
+		}
+	}
+}

+ 44 - 0
internal/handler/label_tagging/get_label_tagging_list_handler.go

@@ -0,0 +1,44 @@
+package label_tagging
+
+import (
+	"net/http"
+
+	"github.com/zeromicro/go-zero/rest/httpx"
+
+	"wechat-api/internal/logic/label_tagging"
+	"wechat-api/internal/svc"
+	"wechat-api/internal/types"
+)
+
+// swagger:route post /label_tagging/list label_tagging GetLabelTaggingList
+//
+// Get label tagging list | 获取LabelTagging信息列表
+//
+// Get label tagging list | 获取LabelTagging信息列表
+//
+// Parameters:
+//  + name: body
+//    require: true
+//    in: body
+//    type: LabelTaggingListReq
+//
+// Responses:
+//  200: LabelTaggingListResp
+
+func GetLabelTaggingListHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
+	return func(w http.ResponseWriter, r *http.Request) {
+		var req types.LabelTaggingListReq
+		if err := httpx.Parse(r, &req, true); err != nil {
+			httpx.ErrorCtx(r.Context(), w, err)
+			return
+		}
+
+		l := label_tagging.NewGetLabelTaggingListLogic(r.Context(), svcCtx)
+		resp, err := l.GetLabelTaggingList(&req)
+		if err != nil {
+			httpx.ErrorCtx(r.Context(), w, err)
+		} else {
+			httpx.OkJsonCtx(r.Context(), w, resp)
+		}
+	}
+}

+ 44 - 0
internal/handler/label_tagging/update_label_tagging_handler.go

@@ -0,0 +1,44 @@
+package label_tagging
+
+import (
+	"net/http"
+
+	"github.com/zeromicro/go-zero/rest/httpx"
+
+	"wechat-api/internal/logic/label_tagging"
+	"wechat-api/internal/svc"
+	"wechat-api/internal/types"
+)
+
+// swagger:route post /label_tagging/update label_tagging UpdateLabelTagging
+//
+// Update label tagging information | 更新LabelTagging信息
+//
+// Update label tagging information | 更新LabelTagging信息
+//
+// Parameters:
+//  + name: body
+//    require: true
+//    in: body
+//    type: LabelTaggingInfo
+//
+// Responses:
+//  200: BaseMsgResp
+
+func UpdateLabelTaggingHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
+	return func(w http.ResponseWriter, r *http.Request) {
+		var req types.LabelTaggingInfo
+		if err := httpx.Parse(r, &req, true); err != nil {
+			httpx.ErrorCtx(r.Context(), w, err)
+			return
+		}
+
+		l := label_tagging.NewUpdateLabelTaggingLogic(r.Context(), svcCtx)
+		resp, err := l.UpdateLabelTagging(&req)
+		if err != nil {
+			httpx.ErrorCtx(r.Context(), w, err)
+		} else {
+			httpx.OkJsonCtx(r.Context(), w, resp)
+		}
+	}
+}

+ 50 - 0
internal/handler/routes.go

@@ -32,6 +32,7 @@ import (
 	employee_config "wechat-api/internal/handler/employee_config"
 	label "wechat-api/internal/handler/label"
 	label_relationship "wechat-api/internal/handler/label_relationship"
+	label_tagging "wechat-api/internal/handler/label_tagging"
 	message_records "wechat-api/internal/handler/message_records"
 	openapi "wechat-api/internal/handler/openapi"
 	pay_recharge "wechat-api/internal/handler/pay_recharge"
@@ -131,6 +132,11 @@ func RegisterHandlers(server *rest.Server, serverCtx *svc.ServiceContext) {
 				},
 				{
 					Method:  http.MethodPost,
+					Path:    "/wx/selectList",
+					Handler: Wx.GetSelectWxListHandler(serverCtx),
+				},
+				{
+					Method:  http.MethodPost,
 					Path:    "/wx/getWxAllowBlockList",
 					Handler: Wx.GetWxAllowBlockListHandler(serverCtx),
 				},
@@ -444,6 +450,40 @@ func RegisterHandlers(server *rest.Server, serverCtx *svc.ServiceContext) {
 	)
 
 	server.AddRoutes(
+		rest.WithMiddlewares(
+			[]rest.Middleware{serverCtx.Authority},
+			[]rest.Route{
+				{
+					Method:  http.MethodPost,
+					Path:    "/label_tagging/create",
+					Handler: label_tagging.CreateLabelTaggingHandler(serverCtx),
+				},
+				{
+					Method:  http.MethodPost,
+					Path:    "/label_tagging/update",
+					Handler: label_tagging.UpdateLabelTaggingHandler(serverCtx),
+				},
+				{
+					Method:  http.MethodPost,
+					Path:    "/label_tagging/delete",
+					Handler: label_tagging.DeleteLabelTaggingHandler(serverCtx),
+				},
+				{
+					Method:  http.MethodPost,
+					Path:    "/label_tagging/list",
+					Handler: label_tagging.GetLabelTaggingListHandler(serverCtx),
+				},
+				{
+					Method:  http.MethodPost,
+					Path:    "/label_tagging",
+					Handler: label_tagging.GetLabelTaggingByIdHandler(serverCtx),
+				},
+			}...,
+		),
+		rest.WithJwt(serverCtx.Config.Auth.AccessSecret),
+	)
+
+	server.AddRoutes(
 		[]rest.Route{
 			{
 				Method:  http.MethodPost,
@@ -586,6 +626,11 @@ func RegisterHandlers(server *rest.Server, serverCtx *svc.ServiceContext) {
 					Path:    "/sop_stage/move",
 					Handler: sop_stage.MoveSopStageHandler(serverCtx),
 				},
+				{
+					Method:  http.MethodPost,
+					Path:    "/sop_stage/copy",
+					Handler: sop_stage.SopStageCopyHandler(serverCtx),
+				},
 			}...,
 		),
 		rest.WithJwt(serverCtx.Config.Auth.AccessSecret),
@@ -1589,6 +1634,11 @@ func RegisterHandlers(server *rest.Server, serverCtx *svc.ServiceContext) {
 				Path:    "/api/xiaoice/message",
 				Handler: xiaoice.GptbotsMessageHandler(serverCtx),
 			},
+			{
+				Method:  http.MethodPost,
+				Path:    "/api/xiaoice/chat",
+				Handler: xiaoice.GptbotsChatHandler(serverCtx),
+			},
 		},
 	)
 

+ 44 - 0
internal/handler/sop_stage/sop_stage_copy_handler.go

@@ -0,0 +1,44 @@
+package sop_stage
+
+import (
+	"net/http"
+
+	"github.com/zeromicro/go-zero/rest/httpx"
+
+	"wechat-api/internal/logic/sop_stage"
+	"wechat-api/internal/svc"
+	"wechat-api/internal/types"
+)
+
+// swagger:route post /sop_stage/copy sop_stage SopStageCopy
+//
+// stage copy | SopStage 复制
+//
+// stage copy | SopStage 复制
+//
+// Parameters:
+//  + name: body
+//    require: true
+//    in: body
+//    type: StageCopyReq
+//
+// Responses:
+//  200: BaseMsgResp
+
+func SopStageCopyHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
+	return func(w http.ResponseWriter, r *http.Request) {
+		var req types.StageCopyReq
+		if err := httpx.Parse(r, &req, true); err != nil {
+			httpx.ErrorCtx(r.Context(), w, err)
+			return
+		}
+
+		l := sop_stage.NewSopStageCopyLogic(r.Context(), svcCtx)
+		resp, err := l.SopStageCopy(&req)
+		if err != nil {
+			httpx.ErrorCtx(r.Context(), w, err)
+		} else {
+			httpx.OkJsonCtx(r.Context(), w, resp)
+		}
+	}
+}

+ 44 - 0
internal/handler/xiaoice/gptbots_chat_handler.go

@@ -0,0 +1,44 @@
+package xiaoice
+
+import (
+	"net/http"
+
+	"github.com/zeromicro/go-zero/rest/httpx"
+
+	"wechat-api/internal/logic/xiaoice"
+	"wechat-api/internal/svc"
+	"wechat-api/internal/types"
+)
+
+// swagger:route post /api/xiaoice/chat xiaoice GptbotsChat
+//
+// gen gptbots | message 接口的升级版,支持 avatar_id 参数
+//
+// gen gptbots | message 接口的升级版,支持 avatar_id 参数
+//
+// Parameters:
+//  + name: body
+//    require: true
+//    in: body
+//    type: ChatReq
+//
+// Responses:
+//  200: BaseDataInfo
+
+func GptbotsChatHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
+	return func(w http.ResponseWriter, r *http.Request) {
+		var req types.ChatReq
+		if err := httpx.Parse(r, &req, true); err != nil {
+			httpx.ErrorCtx(r.Context(), w, err)
+			return
+		}
+
+		l := xiaoice.NewGptbotsChatLogic(r.Context(), svcCtx)
+		resp, err := l.GptbotsChat(&req)
+		if err != nil {
+			httpx.ErrorCtx(r.Context(), w, err)
+		} else {
+			httpx.OkJsonCtx(r.Context(), w, resp)
+		}
+	}
+}

+ 65 - 0
internal/logic/Wx/get_select_wx_list_logic.go

@@ -0,0 +1,65 @@
+package Wx
+
+import (
+	"context"
+	"github.com/suyuan32/simple-admin-common/msg/errormsg"
+	"strings"
+	"wechat-api/ent"
+	"wechat-api/ent/predicate"
+	"wechat-api/ent/wx"
+	"wechat-api/internal/utils/dberrorhandler"
+
+	"wechat-api/internal/svc"
+	"wechat-api/internal/types"
+
+	"github.com/zeromicro/go-zero/core/logx"
+)
+
+type GetSelectWxListLogic struct {
+	logx.Logger
+	ctx    context.Context
+	svcCtx *svc.ServiceContext
+}
+
+func NewGetSelectWxListLogic(ctx context.Context, svcCtx *svc.ServiceContext) *GetSelectWxListLogic {
+	return &GetSelectWxListLogic{
+		Logger: logx.WithContext(ctx),
+		ctx:    ctx,
+		svcCtx: svcCtx}
+}
+
+func (l *GetSelectWxListLogic) GetSelectWxList(req *types.WxSelectListReq) (resp *types.WxSelectListResp, err error) {
+	organizationId := l.ctx.Value("organizationId").(uint64)
+	isAdmin := l.ctx.Value("isAdmin").(bool)
+	var predicates []predicate.Wx
+	if !isAdmin {
+		predicates = append(predicates, wx.OrganizationIDEQ(organizationId))
+	} else {
+		if req.OrganizationId != nil && *req.OrganizationId != 0 {
+			predicates = append(predicates, wx.OrganizationIDEQ(*req.OrganizationId))
+		}
+	}
+	data, err := l.svcCtx.DB.Wx.Query().Where(predicates...).Order(ent.Desc(wx.FieldOrganizationID)).All(l.ctx)
+	if err != nil {
+		return nil, dberrorhandler.DefaultEntError(l.Logger, err, req)
+	}
+
+	resp = &types.WxSelectListResp{}
+	resp.Msg = errormsg.Success
+
+	for _, v := range data {
+		wxid := v.Wxid
+		if !strings.HasPrefix(wxid, "temp-") {
+			resp.Data = append(resp.Data,
+				types.WxSelectListInfo{
+					BaseIDInfo: types.BaseIDInfo{
+						Id: &v.ID,
+					},
+					Wxid:     &wxid,
+					Nickname: &v.Nickname,
+				})
+		}
+	}
+
+	return resp, nil
+}

+ 7 - 2
internal/logic/Wx/get_wx_list_logic.go

@@ -5,6 +5,7 @@ import (
 	"fmt"
 	reqv3 "github.com/imroc/req/v3"
 	"github.com/suyuan32/simple-admin-core/rpc/types/core"
+	"strings"
 	"wechat-api/ent"
 	"wechat-api/ent/predicate"
 	"wechat-api/ent/usagetotal"
@@ -105,7 +106,10 @@ func (l *GetWxListLogic) GetWxList(req *types.WxListReq) (*types.WxListResp, err
 	for _, v := range data.List {
 		// 创建 hookClient 客户端
 		serverInfo := serverSet[v.ServerID]
-
+		serverName := serverInfo.Name
+		if strings.HasPrefix(strings.ToUpper(v.Port), "PC-") {
+			serverName = "本地版"
+		}
 		var loginStatus uint8 = 0
 		hookClient := hook.NewHook(serverInfo.PrivateIP, serverInfo.AdminPort, v.Port)
 		if v.ServerID > 0 {
@@ -205,6 +209,7 @@ func (l *GetWxListLogic) GetWxList(req *types.WxListReq) (*types.WxListResp, err
 				Examples:   &v.Edges.Agent.Examples,
 			}
 		}
+
 		resp.Data.Data = append(resp.Data.Data,
 			types.WxInfo{
 				BaseIDInfo: types.BaseIDInfo{
@@ -214,7 +219,7 @@ func (l *GetWxListLogic) GetWxList(req *types.WxListReq) (*types.WxListResp, err
 				},
 				Status:           &loginStatus,
 				ServerId:         &v.ServerID,
-				ServerName:       &serverInfo.Name,
+				ServerName:       &serverName,
 				Port:             &v.Port,
 				ProcessId:        &processID,
 				Callback:         &v.Callback,

+ 15 - 9
internal/logic/Wxhook/get_friends_and_groups_logic.go

@@ -55,13 +55,13 @@ type GetWechatFriendListResp struct {
 }
 
 func (l *GetFriendsAndGroupsLogic) GetFriendsAndGroups(req *types.IDReq) (resp *types.BaseMsgResp, err error) {
-	organizationId := l.ctx.Value("organizationId").(uint64)
+	//organizationId := l.ctx.Value("organizationId").(uint64)
 	wxInfo, err := l.svcCtx.DB.Wx.Get(l.ctx, req.Id)
-	if err != nil {
+	if err != nil || wxInfo == nil {
 		l.Error("查询微信信息失败", err)
 		return
 	}
-
+	organizationId := wxInfo.OrganizationID
 	if wxInfo.ServerID > 0 {
 		//云托管版本
 		serverInfo, err := l.svcCtx.DB.Server.Get(l.ctx, wxInfo.ServerID)
@@ -95,9 +95,9 @@ func (l *GetFriendsAndGroupsLogic) GetFriendsAndGroups(req *types.IDReq) (resp *
 					SetDontseeme(cast.ToInt(friend.Dontseeme)).
 					SetLag(friend.Lag).
 					SetV3(friend.V3).
+					SetOrganizationID(organizationId).
 					OnConflict().
 					UpdateNewValues().
-					SetOrganizationID(organizationId).
 					ID(l.ctx)
 				if err == nil {
 					lags := splitStringToIntArray(friend.Lag)
@@ -153,11 +153,14 @@ func (l *GetFriendsAndGroupsLogic) GetFriendsAndGroups(req *types.IDReq) (resp *
 				if len(newFriendIds) > 0 && len(newLagIds) > 0 {
 					for id, lags := range newFriendIds {
 						for _, lag := range lags {
-							l.svcCtx.DB.LabelRelationship.Create().
-								SetLabelID(wxSysSet[lag]).
-								SetContactID(id).
-								SetOrganizationID(organizationId).
-								Save(l.ctx)
+							label_id := wxSysSet[lag]
+							if label_id != 0 {
+								l.svcCtx.DB.LabelRelationship.Create().
+									SetLabelID(label_id).
+									SetContactID(id).
+									SetOrganizationID(organizationId).
+									Save(l.ctx)
+							}
 						}
 					}
 				}
@@ -175,6 +178,7 @@ func (l *GetFriendsAndGroupsLogic) GetFriendsAndGroups(req *types.IDReq) (resp *
 					SetGname(chatroom.Gname).
 					SetMarkname(chatroom.Markname).
 					SetV3(chatroom.V3).
+					SetOrganizationID(organizationId).
 					OnConflict().
 					UpdateNewValues().
 					ID(l.ctx)
@@ -192,6 +196,7 @@ func (l *GetFriendsAndGroupsLogic) GetFriendsAndGroups(req *types.IDReq) (resp *
 					SetNickname(gh.Nickname).
 					SetMarkname(gh.Markname).
 					SetV3(gh.V3).
+					SetOrganizationID(organizationId).
 					OnConflict().
 					UpdateNewValues().
 					ID(l.ctx)
@@ -228,6 +233,7 @@ func (l *GetFriendsAndGroupsLogic) GetFriendsAndGroups(req *types.IDReq) (resp *
 				SetNickname(friend.Nickname).
 				SetHeadimg(friend.Avatar).
 				SetSex(cast.ToInt(friend.Gender)).
+				SetOrganizationID(organizationId).
 				OnConflict().
 				UpdateNewValues().
 				SetOrganizationID(organizationId).

+ 1 - 1
internal/logic/Wxhook/logout_logic.go

@@ -48,7 +48,7 @@ func (l *LogoutLogic) Logout(req *types.IDReq) (resp *types.BaseMsgResp, err err
 	tmpWxid := rand.New(rand.NewSource(time.Now().UnixNano())).Intn(1000000)
 	l.svcCtx.DB.Wx.UpdateOne(wxInfo).
 		SetStatus(0).
-		SetWxid(strconv.Itoa(tmpWxid)).
+		SetWxid("temp-" + strconv.Itoa(tmpWxid)).
 		Save(l.ctx)
 
 	resp = &types.BaseMsgResp{

+ 8 - 1
internal/logic/contact/add_new_friend_logic.go

@@ -2,6 +2,7 @@ package contact
 
 import (
 	"context"
+	"wechat-api/ent/predicate"
 	"wechat-api/hook"
 
 	"wechat-api/ent/wx"
@@ -27,7 +28,13 @@ func NewAddNewFriendLogic(ctx context.Context, svcCtx *svc.ServiceContext) *AddN
 
 func (l *AddNewFriendLogic) AddNewFriend(req *types.AddNewFriendReq) (*types.BaseMsgResp, error) {
 	organizationId := l.ctx.Value("organizationId").(uint64)
-	wxInfo, err := l.svcCtx.DB.Wx.Query().Where(wx.Wxid(req.OwnerWxid), wx.OrganizationIDEQ(organizationId)).First(l.ctx)
+	isAdmin := l.ctx.Value("isAdmin").(bool)
+	var predicates []predicate.Wx
+	predicates = append(predicates, wx.Wxid(req.OwnerWxid))
+	if !isAdmin {
+		predicates = append(predicates, wx.OrganizationIDEQ(organizationId))
+	}
+	wxInfo, err := l.svcCtx.DB.Wx.Query().Where(predicates...).First(l.ctx)
 	if err != nil {
 		l.Error("查询微信信息失败", err)
 		return nil, err

+ 2 - 1
internal/logic/contact/get_contact_list_logic.go

@@ -58,7 +58,6 @@ func (l *GetContactListLogic) GetContactList(req *types.ContactListReq) (*types.
 			labelrelationship.HasLabelsWith(
 				label.IDIn(req.LabelIDs...),
 			),
-			labelrelationship.DeletedAtIsNil(),
 		))
 	}
 	if req.WxWxid != nil {
@@ -75,6 +74,8 @@ func (l *GetContactListLogic) GetContactList(req *types.ContactListReq) (*types.
 	}
 	if req.Type != nil {
 		predicates = append(predicates, contact.TypeEQ(*req.Type))
+	} else {
+		predicates = append(predicates, contact.Or(contact.TypeEQ(1), contact.TypeEQ(2)))
 	}
 	data, err := l.svcCtx.DB.Contact.Query().Where(predicates...).WithContactRelationships(func(query *ent.LabelRelationshipQuery) {
 		query.WithLabels()

+ 165 - 38
internal/logic/dashboard/get_charts_logic.go

@@ -4,11 +4,13 @@ import (
 	"context"
 	"fmt"
 	"github.com/suyuan32/simple-admin-common/msg/errormsg"
+	"math"
 	"strconv"
 	"time"
 	"wechat-api/ent/custom_types"
 	"wechat-api/ent/label"
 	"wechat-api/ent/predicate"
+	"wechat-api/ent/usagedetail"
 	"wechat-api/ent/usagestatisticday"
 	"wechat-api/ent/usagestatistichour"
 	"wechat-api/internal/svc"
@@ -44,14 +46,13 @@ func (l *GetChartsLogic) GetCharts(req *types.ChartsReq) (resp *types.ChartsResp
 	// 获取组织id
 	var organizationId uint64 = 0
 	isAdmin := l.ctx.Value("isAdmin").(bool)
-	if isAdmin && req.OrganizationId != nil && *req.OrganizationId != 0 {
+	if isAdmin {
 		if req.OrganizationId != nil && *req.OrganizationId != 0 {
 			organizationId = *req.OrganizationId
 		}
 	} else {
 		organizationId = l.ctx.Value("organizationId").(uint64)
 	}
-
 	// 解析起始和截止时间
 	layouts := []string{
 		"2006-01",    // 对应 "2024-01"
@@ -96,76 +97,136 @@ func (l *GetChartsLogic) GetCharts(req *types.ChartsReq) (resp *types.ChartsResp
 		isCurrentDay = endTime.Year() == now.Year() && endTime.Month() == now.Month() && endTime.Day() == now.Day()
 	}
 
+	aiResponseTip := "AI角色 + SOP 执行次数"
+	sopRunTip := "SOP 节点或阶段的触发次数"
+	totalFriendTip := "截止至各统计时点的好友数量"
+	totalGroupTip := "截止至各统计时点的群数量"
+	activeUserTip := "统计周期内回复sop 或触发了AI角色的微信用户"
+	newUserTip := "统计周期内好友的增减数量"
+
 	// 定义变量
 	aiResponse := types.ChartsUint{}
+	aiResponse.Tip = &aiResponseTip
 	sopRun := types.ChartsUint{}
+	sopRun.Tip = &sopRunTip
 	totalFriend := types.ChartsUint{}
+	totalFriend.Tip = &totalFriendTip
 	totalGroup := types.ChartsUint{}
+	totalGroup.Tip = &totalGroupTip
 	accountBalance := types.ChartsUint{}
+	accountBalance.LabelText = "积分"
 	consumeToken := types.ChartsUint{}
 	activeUser := types.ChartsUint{}
+	activeUser.Tip = &activeUserTip
 	newUser := types.ChartsInt{}
+	newUser.Tip = &newUserTip
 	var labelDists []custom_types.LabelDist
-
-	if isCurrentDay && layoutsType == 1 && req.StartDate == req.EndDate {
-		// 返回当日每小时的数据
-		startOfDay := time.Date(now.Year(), now.Month(), now.Day(), 0, 0, 0, 0, time.UTC)
-		startAddTimeString := startOfDay.Format("2006010200")
+	if layoutsType == 1 && *req.StartDate == *req.EndDate {
+		startAddTimeString := startTime.Format("2006010200")
 		startAddTime, err := strconv.ParseUint(startAddTimeString, 10, 64)
 		if err != nil {
 			fmt.Println("转换开始时间失败:", err)
 			return nil, err
 		}
 
+		nextDayMidnight := time.Date(startTime.Year(), startTime.Month(), startTime.Day()+1, 0, 0, 0, 0, startTime.Location())
+		nextDayMidnightString := nextDayMidnight.Format("2006010200")
+		nextDayAddTime, err := strconv.ParseUint(nextDayMidnightString, 10, 64)
+		if err != nil {
+			fmt.Println("转换次日0点时间失败:", err)
+			return nil, err
+		}
+
 		var predicates []predicate.UsageStatisticHour
-		if organizationId != 0 {
+		if req.Wxid != nil {
+			if organizationId != 0 {
+				predicates = append(predicates, usagestatistichour.OrganizationID(organizationId))
+			}
+			predicates = append(predicates, usagestatistichour.BotID(*req.Wxid))
+		} else {
 			predicates = append(predicates, usagestatistichour.OrganizationID(organizationId))
+			predicates = append(predicates, usagestatistichour.BotID(""))
 		}
-		predicates = append(predicates, usagestatistichour.BotIDIsNil())
 		predicates = append(predicates, usagestatistichour.AddtimeGTE(startAddTime))
+		predicates = append(predicates, usagestatistichour.AddtimeLT(nextDayAddTime))
 		usageStatisticHour, err := l.svcCtx.DB.UsageStatisticHour.Query().Where(predicates...).All(l.ctx)
 		if err != nil {
 			return nil, err
 		}
 		for _, hourData := range usageStatisticHour {
 			addtimeLastTwoDigits := hourData.Addtime % 100
-
 			aiResponse.Count += hourData.AiResponse
 			aiResponse.Val = append(aiResponse.Val, hourData.AiResponse)
+			aiResponse.Label = append(aiResponse.Label, fmt.Sprintf("%02d-%02d点", addtimeLastTwoDigits, addtimeLastTwoDigits+1))
+			aiResponse.LabelText = "次"
 
 			sopRun.Count += hourData.SopRun
 			sopRun.Val = append(sopRun.Val, hourData.SopRun)
+			sopRun.Label = append(sopRun.Label, fmt.Sprintf("%02d-%02d点", addtimeLastTwoDigits, addtimeLastTwoDigits+1))
+			sopRun.LabelText = "次"
 
 			totalFriend.Count = hourData.TotalFriend
 			totalFriend.Val = append(totalFriend.Val, hourData.TotalFriend)
+			totalFriend.Label = append(totalFriend.Label, fmt.Sprintf("%02d点", addtimeLastTwoDigits+1))
+			totalFriend.LabelText = "个"
 
 			totalGroup.Count = hourData.TotalGroup
 			totalGroup.Val = append(totalGroup.Val, hourData.TotalGroup)
+			totalGroup.Label = append(totalGroup.Label, fmt.Sprintf("%02d点", addtimeLastTwoDigits+1))
+			totalGroup.LabelText = "个"
 
 			consumeToken.Count += hourData.ConsumeToken
 			consumeToken.Val = append(consumeToken.Val, hourData.ConsumeToken)
-			consumeToken.Label = append(consumeToken.Label, fmt.Sprintf("%02d", addtimeLastTwoDigits))
+			consumeToken.Label = append(consumeToken.Label, fmt.Sprintf("%02d-%02d点", addtimeLastTwoDigits, addtimeLastTwoDigits+1))
+			consumeToken.LabelText = "token"
 
-			activeUser.Count = hourData.ActiveUser
+			//activeUser.Count = hourData.ActiveUser
 			activeUser.Val = append(activeUser.Val, hourData.ActiveUser)
+			activeUser.Label = append(activeUser.Label, fmt.Sprintf("%02d-%02d点", addtimeLastTwoDigits, addtimeLastTwoDigits+1))
+			activeUser.LabelText = "个"
 
 			newUser.Count += hourData.NewUser
 			newUser.Val = append(newUser.Val, hourData.NewUser)
-			newUser.Label = append(newUser.Label, fmt.Sprintf("%02d", addtimeLastTwoDigits))
+			newUser.Label = append(newUser.Label, fmt.Sprintf("%02d-%02d点", addtimeLastTwoDigits, addtimeLastTwoDigits+1))
+			newUser.LabelText = "个"
+		}
+
+		// 活跃好友:usage_detail 表 type = 1
+		var usageDetailPredicates []predicate.UsageDetail
+		if organizationId != 0 {
+			usageDetailPredicates = append(usageDetailPredicates, usagedetail.OrganizationID(organizationId))
 		}
+		if req.Wxid != nil {
+			usageDetailPredicates = append(usageDetailPredicates, usagedetail.BotID(*req.Wxid))
+		}
+		usageDetailPredicates = append(usageDetailPredicates, usagedetail.Type(1))
+		usageDetailPredicates = append(usageDetailPredicates, usagedetail.CreatedAtGTE(startTime))
+		usageDetailPredicates = append(usageDetailPredicates, usagedetail.CreatedAtLT(nextDayMidnight))
+		activeUsers, _ := l.svcCtx.DB.UsageDetail.Query().Where(usageDetailPredicates...).GroupBy(usagedetail.FieldReceiverID).Strings(l.ctx)
+		activeUser.Count = uint64(len(activeUsers))
+
 		hourLen := len(usageStatisticHour)
 		if hourLen > 0 {
 			if usageStatisticHour[0].TotalFriend > 0 {
-				totalFriend.Rate = float32((usageStatisticHour[hourLen-1].TotalFriend - usageStatisticHour[0].TotalFriend) / usageStatisticHour[0].TotalFriend)
+				totalFriendRate := float32((float64(usageStatisticHour[hourLen-1].TotalFriend) - float64(usageStatisticHour[0].TotalFriend)) / float64(usageStatisticHour[0].TotalFriend))
+				totalFriendRateRound := float32(math.Round(float64(totalFriendRate) * 100))
+				totalFriend.Rate = &totalFriendRateRound
+				//totalFriend.Rate = &totalFriendRate
 			}
 			if usageStatisticHour[0].TotalGroup > 0 {
-				totalGroup.Rate = float32((usageStatisticHour[hourLen-1].TotalGroup - usageStatisticHour[0].TotalGroup) / usageStatisticHour[0].TotalGroup)
-			}
-			if usageStatisticHour[0].ActiveUser > 0 {
-				activeUser.Rate = float32((usageStatisticHour[hourLen-1].ActiveUser - usageStatisticHour[0].ActiveUser) / usageStatisticHour[0].ActiveUser)
+				totalGroupRate := float32((float64(usageStatisticHour[hourLen-1].TotalGroup) - float64(usageStatisticHour[0].TotalGroup)) / float64(usageStatisticHour[0].TotalGroup))
+				totalGroupRateRound := float32(math.Round(float64(totalGroupRate) * 100))
+				totalGroup.Rate = &totalGroupRateRound
 			}
+			//if usageStatisticHour[0].ActiveUser > 0 {
+			//	activeUserRate := float32((float64(usageStatisticHour[hourLen-1].ActiveUser) - float64(usageStatisticHour[0].ActiveUser)) / float64(usageStatisticHour[0].ActiveUser))
+			//	activeUserRateRound := float32(math.Round(float64(activeUserRate)*100))
+			//	activeUser.Rate = &activeUserRateRound
+			//}
 			if usageStatisticHour[0].NewUser > 0 {
-				newUser.Rate = float32((usageStatisticHour[hourLen-1].NewUser - usageStatisticHour[0].NewUser) / usageStatisticHour[0].NewUser)
+				newUserRate := float32((float64(usageStatisticHour[hourLen-1].NewUser) - float64(usageStatisticHour[0].NewUser)) / float64(usageStatisticHour[0].NewUser))
+				newUserRateRound := float32(math.Round(float64(newUserRate) * 100))
+				newUser.Rate = &newUserRateRound
 			}
 			labelDists = usageStatisticHour[hourLen-1].LabelDist
 		}
@@ -179,16 +240,23 @@ func (l *GetChartsLogic) GetCharts(req *types.ChartsReq) (resp *types.ChartsResp
 		}
 		endAddTimeString := endTime.Format("20060102")
 		endAddTime, err := strconv.ParseUint(endAddTimeString, 10, 64)
+
+		nextDayMidnight := time.Date(endTime.Year(), endTime.Month(), endTime.Day()+1, 0, 0, 0, 0, endTime.Location())
 		if err != nil {
 			fmt.Println("转换截止时间失败:", err)
 			return nil, err
 		}
 
 		var predicatesDay []predicate.UsageStatisticDay
-		if organizationId != 0 {
+		if req.Wxid != nil {
+			if organizationId != 0 {
+				predicatesDay = append(predicatesDay, usagestatisticday.OrganizationID(organizationId))
+			}
+			predicatesDay = append(predicatesDay, usagestatisticday.BotID(*req.Wxid))
+		} else {
 			predicatesDay = append(predicatesDay, usagestatisticday.OrganizationID(organizationId))
+			predicatesDay = append(predicatesDay, usagestatisticday.BotID(""))
 		}
-		predicatesDay = append(predicatesDay, usagestatisticday.BotIDIsNil())
 		predicatesDay = append(predicatesDay, usagestatisticday.AddtimeGTE(startAddTime))
 		predicatesDay = append(predicatesDay, usagestatisticday.AddtimeLTE(endAddTime))
 		usageStatisticDay, err := l.svcCtx.DB.UsageStatisticDay.Query().Where(predicatesDay...).All(l.ctx)
@@ -198,40 +266,60 @@ func (l *GetChartsLogic) GetCharts(req *types.ChartsReq) (resp *types.ChartsResp
 		for _, dayData := range usageStatisticDay {
 			aiResponse.Count = aiResponse.Count + dayData.AiResponse
 			aiResponse.Val = append(aiResponse.Val, dayData.AiResponse)
+			aiResponse.Label = append(aiResponse.Label, fmt.Sprintf("%d", dayData.Addtime))
+			aiResponse.LabelText = "次"
 
 			sopRun.Count += dayData.SopRun
 			sopRun.Val = append(sopRun.Val, dayData.SopRun)
+			sopRun.Label = append(sopRun.Label, fmt.Sprintf("%d", dayData.Addtime))
+			sopRun.LabelText = "次"
 
 			totalFriend.Count = dayData.TotalFriend
 			totalFriend.Val = append(totalFriend.Val, dayData.TotalFriend)
+			totalFriend.Label = append(totalFriend.Label, fmt.Sprintf("%d", dayData.Addtime))
+			totalFriend.LabelText = "个"
 
 			totalGroup.Count = dayData.TotalGroup
 			totalGroup.Val = append(totalGroup.Val, dayData.TotalGroup)
+			totalGroup.Label = append(totalGroup.Label, fmt.Sprintf("%d", dayData.Addtime))
+			totalGroup.LabelText = "个"
 
 			consumeToken.Count += dayData.ConsumeToken
 			consumeToken.Val = append(consumeToken.Val, dayData.ConsumeToken)
 			consumeToken.Label = append(consumeToken.Label, fmt.Sprintf("%d", dayData.Addtime))
+			consumeToken.LabelText = "token"
 
-			activeUser.Count = dayData.ActiveUser
+			//activeUser.Count = dayData.ActiveUser
 			activeUser.Val = append(activeUser.Val, dayData.ActiveUser)
+			activeUser.Label = append(activeUser.Label, fmt.Sprintf("%d", dayData.Addtime))
+			activeUser.LabelText = "个"
 
 			newUser.Count += dayData.NewUser
 			newUser.Val = append(newUser.Val, dayData.NewUser)
 			newUser.Label = append(newUser.Label, fmt.Sprintf("%d", dayData.Addtime))
+			newUser.LabelText = "个"
 		}
 		dayLen := len(usageStatisticDay)
 		if dayLen > 0 {
 			if usageStatisticDay[0].TotalFriend > 0 {
-				totalFriend.Rate = float32((usageStatisticDay[dayLen-1].TotalFriend - usageStatisticDay[0].TotalFriend) / usageStatisticDay[0].TotalFriend)
+				totalFriendRate := float32((float64(usageStatisticDay[dayLen-1].TotalFriend) - float64(usageStatisticDay[0].TotalFriend)) / float64(usageStatisticDay[0].TotalFriend))
+				totalFriendRateRound := float32(math.Round(float64(totalFriendRate) * 100))
+				totalFriend.Rate = &totalFriendRateRound
 			}
 			if usageStatisticDay[0].TotalGroup > 0 {
-				totalGroup.Rate = float32((usageStatisticDay[dayLen-1].TotalGroup - usageStatisticDay[0].TotalGroup) / usageStatisticDay[0].TotalGroup)
-			}
-			if usageStatisticDay[0].ActiveUser > 0 {
-				activeUser.Rate = float32((usageStatisticDay[dayLen-1].ActiveUser - usageStatisticDay[0].ActiveUser) / usageStatisticDay[0].ActiveUser)
+				totalGroupRate := float32((float64(usageStatisticDay[dayLen-1].TotalGroup) - float64(usageStatisticDay[0].TotalGroup)) / float64(usageStatisticDay[0].TotalGroup))
+				totalGroupRateRound := float32(math.Round(float64(totalGroupRate) * 100))
+				totalGroup.Rate = &totalGroupRateRound
 			}
+			//if usageStatisticDay[0].ActiveUser > 0 {
+			//	activeUserRate := float32((float64(usageStatisticDay[dayLen-1].ActiveUser) - float64(usageStatisticDay[0].ActiveUser)) / float64(usageStatisticDay[0].ActiveUser))
+			//	activeUserRateRound := float32(math.Round(float64(activeUserRate)*100))
+			//	activeUser.Rate = &activeUserRateRound
+			//}
 			if usageStatisticDay[0].NewUser > 0 {
-				newUser.Rate = float32((usageStatisticDay[dayLen-1].NewUser - usageStatisticDay[0].NewUser) / usageStatisticDay[0].NewUser)
+				newUserRate := float32((float64(usageStatisticDay[dayLen-1].NewUser) - float64(usageStatisticDay[0].NewUser)) / float64(usageStatisticDay[0].NewUser))
+				newUserRateRound := float32(math.Round(float64(newUserRate) * 100))
+				newUser.Rate = &newUserRateRound
 			}
 			labelDists = usageStatisticDay[dayLen-1].LabelDist
 		}
@@ -247,10 +335,15 @@ func (l *GetChartsLogic) GetCharts(req *types.ChartsReq) (resp *types.ChartsResp
 			}
 
 			var predicates []predicate.UsageStatisticHour
-			if organizationId != 0 {
+			if req.Wxid != nil {
+				if organizationId != 0 {
+					predicates = append(predicates, usagestatistichour.OrganizationID(organizationId))
+				}
+				predicates = append(predicates, usagestatistichour.BotID(*req.Wxid))
+			} else {
 				predicates = append(predicates, usagestatistichour.OrganizationID(organizationId))
+				predicates = append(predicates, usagestatistichour.BotID(""))
 			}
-			predicates = append(predicates, usagestatistichour.BotIDIsNil())
 			predicates = append(predicates, usagestatistichour.AddtimeGTE(startOfDayAddTime))
 			usageStatisticHour, err := l.svcCtx.DB.UsageStatisticHour.Query().Where(predicates...).All(l.ctx)
 			if err != nil {
@@ -278,46 +371,80 @@ func (l *GetChartsLogic) GetCharts(req *types.ChartsReq) (resp *types.ChartsResp
 
 				aiResponse.Count = aiResponse.Count + aiResponseOfDay
 				aiResponse.Val = append(aiResponse.Val, aiResponseOfDay)
+				aiResponse.Label = append(aiResponse.Label, "今日")
+				aiResponse.LabelText = "次"
 
 				sopRun.Count = sopRun.Count + sopRunOfDay
 				sopRun.Val = append(sopRun.Val, sopRunOfDay)
+				sopRun.Label = append(sopRun.Label, "今日")
+				sopRun.LabelText = "次"
 
 				totalFriend.Count = totalFriendOfDay
 				totalFriend.Val = append(totalFriend.Val, totalFriendOfDay)
+				totalFriend.Label = append(totalFriend.Label, "今日")
 				tfLen := len(totalFriend.Val)
 				if tfLen > 0 && totalFriend.Val[0] > 0 {
-					totalFriend.Rate = float32((totalFriend.Val[tfLen-1] - totalFriend.Val[0]) / totalFriend.Val[0])
+					totalFriendRate := float32((float64(totalFriend.Val[tfLen-1]) - float64(totalFriend.Val[0])) / float64(totalFriend.Val[0]))
+					totalFriendRateRound := float32(math.Round(float64(totalFriendRate) * 100))
+					totalFriend.Rate = &totalFriendRateRound
 				}
+				totalFriend.LabelText = "个"
 
 				totalGroup.Count = totalGroupOfDay
 				totalGroup.Val = append(totalGroup.Val, totalGroupOfDay)
+				totalGroup.Label = append(totalGroup.Label, "今日")
 				tgLen := len(totalGroup.Val)
 				if tgLen > 0 && totalGroup.Val[0] > 0 {
-					totalGroup.Rate = float32((totalGroup.Val[tgLen-1] - totalGroup.Val[0]) / totalGroup.Val[0])
+					totalGroupRate := float32((float64(totalGroup.Val[tgLen-1]) - float64(totalGroup.Val[0])) / float64(totalGroup.Val[0]))
+					totalGroupRateRound := float32(math.Round(float64(totalGroupRate) * 100))
+					totalGroup.Rate = &totalGroupRateRound
 				}
+				totalGroup.LabelText = "个"
 
 				consumeToken.Count = consumeToken.Count + consumeTokenOfDay
 				consumeToken.Val = append(consumeToken.Val, consumeTokenOfDay)
 				consumeToken.Label = append(consumeToken.Label, "今日")
+				consumeToken.LabelText = "token"
 
-				activeUser.Count = activeUserOfDay
+				//activeUser.Count = activeUserOfDay
 				activeUser.Val = append(activeUser.Val, activeUserOfDay)
-				auLen := len(activeUser.Val)
-				if auLen > 0 && activeUser.Val[0] > 0 {
-					activeUser.Rate = float32((activeUser.Val[auLen-1] - activeUser.Val[0]) / activeUser.Val[0])
-				}
+				activeUser.Label = append(activeUser.Label, "今日")
+				//auLen := len(activeUser.Val)
+				//if auLen > 0 && activeUser.Val[0] > 0 {
+				//	activeUserRate := float32((float64(activeUser.Val[auLen-1]) - float64(activeUser.Val[0])) / float64(activeUser.Val[0]))
+				//	activeUserRateRound := float32(math.Round(float64(activeUserRate)*100))
+				//	activeUser.Rate = &activeUserRateRound
+				//}
+				activeUser.LabelText = "个"
 
 				newUser.Count = newUserOfDay
 				newUser.Val = append(newUser.Val, newUserOfDay)
 				newUser.Label = append(newUser.Label, "今日")
 				nuLen := len(newUser.Val)
 				if nuLen > 0 && newUser.Val[0] > 0 {
-					newUser.Rate = float32((newUser.Val[nuLen-1] - newUser.Val[0]) / newUser.Val[0])
+					newUserRate := float32((float64(newUser.Val[nuLen-1]) - float64(newUser.Val[0])) / float64(newUser.Val[0]))
+					newUserRateRound := float32(math.Round(float64(newUserRate) * 100))
+					newUser.Rate = &newUserRateRound
 				}
+				newUser.LabelText = "个"
 
 				labelDists = usageStatisticHour[hourLen-1].LabelDist
 			}
 		}
+
+		// 活跃好友:usage_detail 表 type = 1
+		var usageDetailPredicates []predicate.UsageDetail
+		if organizationId != 0 {
+			usageDetailPredicates = append(usageDetailPredicates, usagedetail.OrganizationID(organizationId))
+		}
+		if req.Wxid != nil {
+			usageDetailPredicates = append(usageDetailPredicates, usagedetail.BotID(*req.Wxid))
+		}
+		usageDetailPredicates = append(usageDetailPredicates, usagedetail.Type(1))
+		usageDetailPredicates = append(usageDetailPredicates, usagedetail.CreatedAtGTE(startTime))
+		usageDetailPredicates = append(usageDetailPredicates, usagedetail.CreatedAtLT(nextDayMidnight))
+		activeUsers, _ := l.svcCtx.DB.UsageDetail.Query().Where(usageDetailPredicates...).GroupBy(usagedetail.FieldReceiverID).Strings(l.ctx)
+		activeUser.Count = uint64(len(activeUsers))
 	}
 
 	var labelIds []uint64

+ 41 - 23
internal/logic/dashboard/get_wxs_logic.go

@@ -4,7 +4,9 @@ import (
 	"context"
 	"fmt"
 	"github.com/suyuan32/simple-admin-common/msg/errormsg"
+	"math"
 	"strconv"
+	"strings"
 	"time"
 	"wechat-api/ent"
 	"wechat-api/ent/predicate"
@@ -74,11 +76,13 @@ func (l *GetWxsLogic) GetWxs(req *types.WxReq) (resp *types.WxResp, err error) {
 	} else {
 		isCurrentDay = endTime.Year() == now.Year() && endTime.Month() == now.Month() && endTime.Day() == now.Day()
 	}
-
 	var predicates []predicate.Wx
 	if organizationId != 0 {
 		predicates = append(predicates, wx.OrganizationID(organizationId))
 	}
+	if req.Wxid != nil {
+		predicates = append(predicates, wx.Wxid(*req.Wxid))
+	}
 	wxs, err := l.svcCtx.DB.Wx.Query().Where(predicates...).All(l.ctx)
 
 	if err != nil {
@@ -91,12 +95,13 @@ func (l *GetWxsLogic) GetWxs(req *types.WxReq) (resp *types.WxResp, err error) {
 	var wxIds []string
 	wxSet := make(map[string]*ent.Wx)
 	for _, w := range wxs {
-		wxIds = append(wxIds, w.Wxid)
-		wxSet[w.Wxid] = w
+		if !strings.HasPrefix(w.Wxid, "temp-") {
+			wxIds = append(wxIds, w.Wxid)
+			wxSet[w.Wxid] = w
+		}
 	}
 
 	var wxList []types.WxData
-
 	if isCurrentDay {
 		// 返回当日每小时的数据
 		var predicatesH []predicate.UsageStatisticHour
@@ -109,7 +114,7 @@ func (l *GetWxsLogic) GetWxs(req *types.WxReq) (resp *types.WxResp, err error) {
 			Order(ent.Desc(usagestatistichour.FieldAddtime)).
 			First(l.ctx)
 		if err != nil {
-			return nil, err
+			return nil, dberrorhandler.DefaultEntError(l.Logger, err, req)
 		}
 		if lastHourData == nil {
 			return nil, err
@@ -118,22 +123,30 @@ func (l *GetWxsLogic) GetWxs(req *types.WxReq) (resp *types.WxResp, err error) {
 		var predicatesHour []predicate.UsageStatisticHour
 		if organizationId != 0 {
 			predicatesHour = append(predicatesHour, usagestatistichour.OrganizationID(organizationId))
-			predicatesHour = append(predicatesHour, usagestatistichour.BotIDIn(wxIds...))
 		}
+		predicatesHour = append(predicatesHour, usagestatistichour.BotIDIn(wxIds...))
 		predicatesHour = append(predicatesHour, usagestatistichour.Addtime(lastHourData.Addtime))
 		usageStatisticHour, err := l.svcCtx.DB.UsageStatisticHour.Query().Where(predicatesHour...).Page(l.ctx, req.Page, req.PageSize)
 		if err != nil {
-			return nil, err
+			return nil, dberrorhandler.DefaultEntError(l.Logger, err, req)
 		}
 		if usageStatisticHour != nil && usageStatisticHour.List != nil {
+			l.Infof("----------------usageStatisticHour 1--------------: %+v", usageStatisticHour)
 			resp.Data.Total = usageStatisticHour.PageDetails.Total
 			for _, hourData := range usageStatisticHour.List {
-				wxList = append(wxList, types.WxData{
-					Nickname:        wxSet[hourData.BotID].Nickname,
-					InteractionRate: float32(hourData.ActiveUser) / float32(hourData.TotalFriend),
-					TotalFriend:     hourData.TotalFriend,
-					TotalGroup:      hourData.TotalGroup,
-				})
+				if wxSet[hourData.BotID] != nil {
+					rate := float32(0)
+					if hourData.TotalFriend != 0 {
+						rate = float32(float64(hourData.ActiveUser)) / float32(float64(hourData.TotalFriend))
+						rate = float32(math.Round(float64(rate) * 100))
+					}
+					wxList = append(wxList, types.WxData{
+						Nickname:        wxSet[hourData.BotID].Nickname,
+						InteractionRate: rate,
+						TotalFriend:     hourData.TotalFriend,
+						TotalGroup:      hourData.TotalGroup,
+					})
+				}
 			}
 		}
 	} else {
@@ -146,8 +159,8 @@ func (l *GetWxsLogic) GetWxs(req *types.WxReq) (resp *types.WxResp, err error) {
 		var predicatesDay []predicate.UsageStatisticDay
 		if organizationId != 0 {
 			predicatesDay = append(predicatesDay, usagestatisticday.OrganizationID(organizationId))
-			predicatesDay = append(predicatesDay, usagestatisticday.BotIDIn(wxIds...))
 		}
+		predicatesDay = append(predicatesDay, usagestatisticday.BotIDIn(wxIds...))
 		predicatesDay = append(predicatesDay, usagestatisticday.Addtime(endAddTime))
 		usageStatisticDay, err := l.svcCtx.DB.UsageStatisticDay.Query().
 			Where(predicatesDay...).Page(l.ctx, req.Page, req.PageSize)
@@ -155,21 +168,26 @@ func (l *GetWxsLogic) GetWxs(req *types.WxReq) (resp *types.WxResp, err error) {
 			return nil, err
 		}
 		if usageStatisticDay != nil && usageStatisticDay.List != nil {
+			l.Infof("----------------usageStatisticDay 2--------------: %+v", usageStatisticDay)
 			resp.Data.Total = usageStatisticDay.PageDetails.Total
 			for _, dayData := range usageStatisticDay.List {
-				rate := float32(0)
-				if dayData.TotalFriend != 0 {
-					rate = float32(dayData.ActiveUser) / float32(dayData.TotalFriend)
+				if wxSet[dayData.BotID] != nil {
+					rate := float32(0)
+					if dayData.TotalFriend != 0 {
+						rate = float32(float64(dayData.ActiveUser)) / float32(float64(dayData.TotalFriend))
+						rate = float32(math.Round(float64(rate) * 100))
+					}
+					wxList = append(wxList, types.WxData{
+						Nickname:        wxSet[dayData.BotID].Nickname,
+						InteractionRate: rate,
+						TotalFriend:     dayData.TotalFriend,
+						TotalGroup:      dayData.TotalGroup,
+					})
 				}
-				wxList = append(wxList, types.WxData{
-					Nickname:        wxSet[dayData.BotID].Nickname,
-					InteractionRate: rate,
-					TotalFriend:     dayData.TotalFriend,
-					TotalGroup:      dayData.TotalGroup,
-				})
 			}
 		}
 	}
+
 	resp.Data.Data = wxList
 
 	return resp, nil

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

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

+ 41 - 0
internal/logic/label_tagging/create_label_tagging_logic.go

@@ -0,0 +1,41 @@
+package label_tagging
+
+import (
+	"context"
+	"github.com/suyuan32/simple-admin-common/msg/errormsg"
+	"wechat-api/internal/utils/dberrorhandler"
+
+	"wechat-api/internal/svc"
+	"wechat-api/internal/types"
+
+	"github.com/zeromicro/go-zero/core/logx"
+)
+
+type CreateLabelTaggingLogic struct {
+	logx.Logger
+	ctx    context.Context
+	svcCtx *svc.ServiceContext
+}
+
+func NewCreateLabelTaggingLogic(ctx context.Context, svcCtx *svc.ServiceContext) *CreateLabelTaggingLogic {
+	return &CreateLabelTaggingLogic{
+		Logger: logx.WithContext(ctx),
+		ctx:    ctx,
+		svcCtx: svcCtx}
+}
+
+func (l *CreateLabelTaggingLogic) CreateLabelTagging(req *types.LabelTaggingInfo) (resp *types.BaseMsgResp, err error) {
+	organizationId := l.ctx.Value("organizationId").(uint64)
+	_, err = l.svcCtx.DB.LabelTagging.Create().
+		SetOrganizationID(organizationId).
+		SetConditions(req.Conditions).
+		SetNotNilActionLabelAdd(req.ActionLabelAdd).
+		SetNotNilActionLabelDel(req.ActionLabelDel).
+		Save(l.ctx)
+
+	if err != nil {
+		return nil, dberrorhandler.DefaultEntError(l.Logger, err, req)
+	}
+	l.svcCtx.Rds.Del(l.ctx, "label_tagging_info")
+	return &types.BaseMsgResp{Msg: errormsg.CreateSuccess}, nil
+}

+ 37 - 0
internal/logic/label_tagging/delete_label_tagging_logic.go

@@ -0,0 +1,37 @@
+package label_tagging
+
+import (
+	"context"
+	"github.com/suyuan32/simple-admin-common/msg/errormsg"
+	"wechat-api/ent/labeltagging"
+	"wechat-api/internal/utils/dberrorhandler"
+
+	"wechat-api/internal/svc"
+	"wechat-api/internal/types"
+
+	"github.com/zeromicro/go-zero/core/logx"
+)
+
+type DeleteLabelTaggingLogic struct {
+	logx.Logger
+	ctx    context.Context
+	svcCtx *svc.ServiceContext
+}
+
+func NewDeleteLabelTaggingLogic(ctx context.Context, svcCtx *svc.ServiceContext) *DeleteLabelTaggingLogic {
+	return &DeleteLabelTaggingLogic{
+		Logger: logx.WithContext(ctx),
+		ctx:    ctx,
+		svcCtx: svcCtx}
+}
+
+func (l *DeleteLabelTaggingLogic) DeleteLabelTagging(req *types.IDsReq) (resp *types.BaseMsgResp, err error) {
+	organizationId := l.ctx.Value("organizationId").(uint64)
+	_, err = l.svcCtx.DB.LabelTagging.Delete().Where(labeltagging.IDIn(req.Ids...), labeltagging.OrganizationID(organizationId)).Exec(l.ctx)
+
+	if err != nil {
+		return nil, dberrorhandler.DefaultEntError(l.Logger, err, req)
+	}
+	l.svcCtx.Rds.Del(l.ctx, "label_tagging_info")
+	return &types.BaseMsgResp{Msg: errormsg.DeleteSuccess}, nil
+}

+ 55 - 0
internal/logic/label_tagging/get_label_tagging_by_id_logic.go

@@ -0,0 +1,55 @@
+package label_tagging
+
+import (
+	"context"
+	"github.com/suyuan32/simple-admin-common/msg/errormsg"
+	"github.com/suyuan32/simple-admin-common/utils/pointy"
+	"wechat-api/ent/labeltagging"
+	"wechat-api/internal/utils/dberrorhandler"
+
+	"wechat-api/internal/svc"
+	"wechat-api/internal/types"
+
+	"github.com/zeromicro/go-zero/core/logx"
+)
+
+type GetLabelTaggingByIdLogic struct {
+	logx.Logger
+	ctx    context.Context
+	svcCtx *svc.ServiceContext
+}
+
+func NewGetLabelTaggingByIdLogic(ctx context.Context, svcCtx *svc.ServiceContext) *GetLabelTaggingByIdLogic {
+	return &GetLabelTaggingByIdLogic{
+		Logger: logx.WithContext(ctx),
+		ctx:    ctx,
+		svcCtx: svcCtx}
+}
+
+func (l *GetLabelTaggingByIdLogic) GetLabelTaggingById(req *types.IDReq) (resp *types.LabelTaggingInfoResp, err error) {
+	organizationId := l.ctx.Value("organizationId").(uint64)
+	data, err := l.svcCtx.DB.LabelTagging.Query().Where(labeltagging.ID(req.Id), labeltagging.OrganizationID(organizationId)).Only(l.ctx)
+	if err != nil {
+		return nil, dberrorhandler.DefaultEntError(l.Logger, err, req)
+	}
+
+	return &types.LabelTaggingInfoResp{
+		BaseDataInfo: types.BaseDataInfo{
+			Code: 0,
+			Msg:  errormsg.Success,
+		},
+		Data: types.LabelTaggingInfo{
+			BaseIDInfo: types.BaseIDInfo{
+				Id:        &data.ID,
+				CreatedAt: pointy.GetPointer(data.CreatedAt.UnixMilli()),
+				UpdatedAt: pointy.GetPointer(data.UpdatedAt.UnixMilli()),
+			},
+			Status:         &data.Status,
+			OrganizationId: &data.OrganizationID,
+			Type:           &data.Type,
+			Conditions:     data.Conditions,
+			ActionLabelAdd: data.ActionLabelAdd,
+			ActionLabelDel: data.ActionLabelDel,
+		},
+	}, nil
+}

+ 69 - 0
internal/logic/label_tagging/get_label_tagging_list_logic.go

@@ -0,0 +1,69 @@
+package label_tagging
+
+import (
+	"context"
+	"github.com/suyuan32/simple-admin-common/msg/errormsg"
+	"github.com/suyuan32/simple-admin-common/utils/pointy"
+	"wechat-api/ent/label"
+	"wechat-api/ent/labeltagging"
+	"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 GetLabelTaggingListLogic struct {
+	logx.Logger
+	ctx    context.Context
+	svcCtx *svc.ServiceContext
+}
+
+func NewGetLabelTaggingListLogic(ctx context.Context, svcCtx *svc.ServiceContext) *GetLabelTaggingListLogic {
+	return &GetLabelTaggingListLogic{
+		Logger: logx.WithContext(ctx),
+		ctx:    ctx,
+		svcCtx: svcCtx}
+}
+
+func (l *GetLabelTaggingListLogic) GetLabelTaggingList(req *types.LabelTaggingListReq) (resp *types.LabelTaggingListResp, err error) {
+	organizationId := l.ctx.Value("organizationId").(uint64)
+	var predicates []predicate.LabelTagging
+	predicates = append(predicates, labeltagging.OrganizationIDEQ(organizationId))
+	data, err := l.svcCtx.DB.LabelTagging.Query().Where(predicates...).Page(l.ctx, req.Page, req.PageSize)
+
+	if err != nil {
+		return nil, dberrorhandler.DefaultEntError(l.Logger, err, req)
+	}
+
+	resp = &types.LabelTaggingListResp{}
+	resp.Msg = errormsg.Success
+	resp.Data.Total = data.PageDetails.Total
+
+	for _, v := range data.List {
+		var labelAddInfo []string
+		labels, _ := l.svcCtx.DB.Label.Query().Where(label.IDIn(v.ActionLabelAdd...)).All(l.ctx)
+		for _, l := range labels {
+			labelAddInfo = append(labelAddInfo, l.Name)
+		}
+		resp.Data.Data = append(resp.Data.Data,
+			types.LabelTaggingInfo{
+				BaseIDInfo: types.BaseIDInfo{
+					Id:        &v.ID,
+					CreatedAt: pointy.GetPointer(v.CreatedAt.UnixMilli()),
+					UpdatedAt: pointy.GetPointer(v.UpdatedAt.UnixMilli()),
+				},
+				Status:         &v.Status,
+				OrganizationId: &v.OrganizationID,
+				Type:           &v.Type,
+				Conditions:     v.Conditions,
+				ActionLabelAdd: v.ActionLabelAdd,
+				LabelAddInfo:   labelAddInfo,
+				ActionLabelDel: v.ActionLabelDel,
+			})
+	}
+
+	return resp, nil
+}

+ 41 - 0
internal/logic/label_tagging/update_label_tagging_logic.go

@@ -0,0 +1,41 @@
+package label_tagging
+
+import (
+	"context"
+	"github.com/suyuan32/simple-admin-common/msg/errormsg"
+	"wechat-api/ent/labeltagging"
+	"wechat-api/internal/utils/dberrorhandler"
+
+	"wechat-api/internal/svc"
+	"wechat-api/internal/types"
+
+	"github.com/zeromicro/go-zero/core/logx"
+)
+
+type UpdateLabelTaggingLogic struct {
+	logx.Logger
+	ctx    context.Context
+	svcCtx *svc.ServiceContext
+}
+
+func NewUpdateLabelTaggingLogic(ctx context.Context, svcCtx *svc.ServiceContext) *UpdateLabelTaggingLogic {
+	return &UpdateLabelTaggingLogic{
+		Logger: logx.WithContext(ctx),
+		ctx:    ctx,
+		svcCtx: svcCtx}
+}
+
+func (l *UpdateLabelTaggingLogic) UpdateLabelTagging(req *types.LabelTaggingInfo) (resp *types.BaseMsgResp, err error) {
+	organizationId := l.ctx.Value("organizationId").(uint64)
+	err = l.svcCtx.DB.LabelTagging.Update().Where(labeltagging.ID(*req.Id), labeltagging.OrganizationID(organizationId)).
+		SetConditions(req.Conditions).
+		SetNotNilActionLabelAdd(req.ActionLabelAdd).
+		SetNotNilActionLabelDel(req.ActionLabelDel).
+		Exec(l.ctx)
+
+	if err != nil {
+		return nil, dberrorhandler.DefaultEntError(l.Logger, err, req)
+	}
+	l.svcCtx.Rds.Del(l.ctx, "label_tagging_info")
+	return &types.BaseMsgResp{Msg: errormsg.UpdateSuccess}, nil
+}

+ 109 - 0
internal/logic/sop_stage/sop_stage_copy_logic.go

@@ -0,0 +1,109 @@
+package sop_stage
+
+import (
+	"context"
+	"github.com/suyuan32/simple-admin-common/msg/errormsg"
+	"wechat-api/ent"
+	"wechat-api/ent/sopnode"
+	"wechat-api/ent/sopstage"
+	"wechat-api/internal/utils/dberrorhandler"
+
+	"wechat-api/internal/svc"
+	"wechat-api/internal/types"
+
+	"github.com/zeromicro/go-zero/core/logx"
+)
+
+type SopStageCopyLogic struct {
+	logx.Logger
+	ctx    context.Context
+	svcCtx *svc.ServiceContext
+}
+
+func NewSopStageCopyLogic(ctx context.Context, svcCtx *svc.ServiceContext) *SopStageCopyLogic {
+	return &SopStageCopyLogic{
+		Logger: logx.WithContext(ctx),
+		ctx:    ctx,
+		svcCtx: svcCtx}
+}
+
+func (l *SopStageCopyLogic) SopStageCopy(req *types.StageCopyReq) (resp *types.BaseMsgResp, err error) {
+	//  查询任务及阶段
+	data, err := l.svcCtx.DB.SopStage.Query().
+		Where(sopstage.ID(req.Id)).
+		Only(l.ctx)
+	if err != nil {
+		return nil, dberrorhandler.DefaultEntError(l.Logger, err, req)
+	}
+
+	//  开始事务
+	tx, err := l.svcCtx.DB.Tx(context.Background())
+	if err != nil {
+		return nil, dberrorhandler.DefaultEntError(l.Logger, err, req)
+	}
+
+	// 查询任务的阶段数量
+	count, err := l.svcCtx.DB.SopStage.Query().Where(sopstage.TaskIDEQ(data.TaskID)).Count(l.ctx)
+
+	//  创建新阶段
+	newStage, err := tx.SopStage.Create().
+		SetTaskID(data.TaskID).
+		SetName(data.Name).
+		SetConditionType(data.ConditionType).
+		SetConditionOperator(data.ConditionOperator).
+		SetConditionList(data.ConditionList).
+		SetNotNilActionMessage(data.ActionMessage).
+		SetNotNilActionLabelAdd(data.ActionLabelAdd).
+		SetNotNilActionLabelDel(data.ActionLabelDel).
+		SetNotNilActionForward(&data.ActionForward).
+		SetIndexSort(count + 1).
+		Save(l.ctx)
+	if err != nil {
+		_ = tx.Rollback()
+		return nil, dberrorhandler.DefaultEntError(l.Logger, err, req)
+	}
+	err = CreateNodes(tx, data.ID, 0, newStage.ID, 0, l.ctx, l.Logger)
+	if err != nil {
+		_ = tx.Rollback()
+		return nil, dberrorhandler.DefaultEntError(l.Logger, err, req)
+	}
+
+	// 所有操作成功,提交事务
+	err = tx.Commit()
+	if err != nil {
+		return nil, dberrorhandler.DefaultEntError(l.Logger, err, req)
+	}
+
+	return &types.BaseMsgResp{Msg: errormsg.CreateSuccess}, nil
+}
+
+func CreateNodes(tx *ent.Tx, stageId uint64, parentId uint64, newStageId uint64, newParentId uint64, ctx context.Context, logger logx.Logger) (err error) {
+	data, err := tx.SopNode.Query().
+		Where(sopnode.StageID(stageId), sopnode.ParentID(parentId)).All(ctx)
+	if err != nil {
+		return nil
+	}
+
+	for _, n := range data {
+		newNode, err := tx.SopNode.Create().
+			SetStageID(newStageId).
+			SetParentID(newParentId).
+			SetName(n.Name).
+			SetConditionType(n.ConditionType).
+			SetConditionList(n.ConditionList).
+			SetNotNilNoReplyCondition(&n.NoReplyCondition).
+			SetNotNilActionMessage(n.ActionMessage).
+			SetNotNilActionLabelAdd(n.ActionLabelAdd).
+			SetNotNilActionLabelDel(n.ActionLabelDel).
+			SetNotNilActionForward(&n.ActionForward).
+			Save(ctx)
+		if err != nil {
+			return err
+		}
+		err = CreateNodes(tx, stageId, n.ID, newStageId, newNode.ID, ctx, logger)
+		if err != nil {
+			return err
+		}
+	}
+	return nil
+}

+ 13 - 3
internal/logic/sop_task/publish_sop_task_logic.go

@@ -5,6 +5,7 @@ import (
 	"errors"
 	"github.com/suyuan32/simple-admin-common/msg/errormsg"
 	"regexp"
+	"strings"
 	"wechat-api/ent"
 	"wechat-api/ent/contact"
 	"wechat-api/ent/custom_types"
@@ -92,8 +93,7 @@ func (l *PublishSopTaskLogic) PublishSopTask(req *types.IDReq) (resp *types.Base
 
 				for _, condition := range stage.ConditionList {
 					subPredicate := contact.HasContactRelationshipsWith(
-						labelrelationship.LabelIDIn(condition.LabelIdList...),
-						labelrelationship.DeletedAtIsNil())
+						labelrelationship.LabelIDIn(condition.LabelIdList...))
 					labelrelationship.OrganizationIDEQ(organizationId)
 					if condition.Equal == 2 {
 						subPredicate = contact.Not(subPredicate)
@@ -156,13 +156,14 @@ func (l *PublishSopTaskLogic) PublishSopTask(req *types.IDReq) (resp *types.Base
 										if message.Meta != nil {
 											meta.Filename = message.Meta.Filename
 										}
+										content := varReplace(message.Content, c)
 										_, err = l.svcCtx.DB.MessageRecords.Create().
 											SetBotWxid(c.WxWxid).
 											SetContactID(0).
 											SetContactType(0).
 											SetContactWxid(forwardWxid).
 											SetContentType(message.Type).
-											SetContent(message.Content).
+											SetContent(content).
 											SetMeta(meta).
 											SetSourceType(sourceType).
 											SetSourceID(stage.ID).
@@ -431,3 +432,12 @@ func splitString(input string) []string {
 	// Split the input string based on the pattern
 	return re.Split(input, -1)
 }
+
+func varReplace(s string, contactInfo *ent.Contact) string {
+	nickname := ""
+	if contactInfo != nil {
+		nickname = contactInfo.Nickname
+	}
+	s = strings.Replace(s, "${nickname}", nickname, -1)
+	return s
+}

+ 12 - 2
internal/logic/sop_task/sop_task_copy_logic.go

@@ -82,6 +82,16 @@ func (l *SopTaskCopyLogic) SopTaskCopy(req *types.CopyReq) (resp *types.BaseMsgR
 			c.LabelIdList = newLabels
 			newConditionList = append(newConditionList, c)
 		}
+		newLabelAdd, err := CreateLabels(tx, s.ActionLabelAdd, targetOrganizationId, l.ctx, l.Logger)
+		if err != nil {
+			_ = tx.Rollback()
+			return nil, dberrorhandler.DefaultEntError(l.Logger, err, req)
+		}
+		newLabelDel, err := CreateLabels(tx, s.ActionLabelDel, targetOrganizationId, l.ctx, l.Logger)
+		if err != nil {
+			_ = tx.Rollback()
+			return nil, dberrorhandler.DefaultEntError(l.Logger, err, req)
+		}
 		newStage, err := tx.SopStage.Create().
 			SetTaskID(newTask.ID).
 			SetName(s.Name).
@@ -89,8 +99,8 @@ func (l *SopTaskCopyLogic) SopTaskCopy(req *types.CopyReq) (resp *types.BaseMsgR
 			SetConditionOperator(s.ConditionOperator).
 			SetConditionList(newConditionList).
 			SetNotNilActionMessage(s.ActionMessage).
-			SetNotNilActionLabelAdd(s.ActionLabelAdd).
-			SetNotNilActionLabelDel(s.ActionLabelDel).
+			SetNotNilActionLabelAdd(newLabelAdd).
+			SetNotNilActionLabelDel(newLabelDel).
 			SetNotNilActionForward(&s.ActionForward).
 			SetIndexSort(s.IndexSort).
 			Save(l.ctx)

+ 175 - 0
internal/logic/xiaoice/gptbots_chat_logic.go

@@ -0,0 +1,175 @@
+package xiaoice
+
+import (
+	"bytes"
+	"context"
+	"encoding/json"
+	"fmt"
+	"github.com/suyuan32/simple-admin-common/msg/errormsg"
+	"github.com/zeromicro/go-zero/core/errorx"
+	"io"
+	"net/http"
+	"net/url"
+	"strconv"
+
+	"wechat-api/internal/svc"
+	"wechat-api/internal/types"
+
+	"github.com/zeromicro/go-zero/core/logx"
+)
+
+type GptbotsChatLogic struct {
+	logx.Logger
+	ctx    context.Context
+	svcCtx *svc.ServiceContext
+}
+
+func NewGptbotsChatLogic(ctx context.Context, svcCtx *svc.ServiceContext) *GptbotsChatLogic {
+	return &GptbotsChatLogic{
+		Logger: logx.WithContext(ctx),
+		ctx:    ctx,
+		svcCtx: svcCtx}
+}
+
+func (l *GptbotsChatLogic) GptbotsChat(req *types.ChatReq) (resp *types.BaseDataInfo, err error) {
+	apikeyMap := map[string]string{
+		"VHPF0W063": "app-hQL7oVq57McK5VBHlsMfhtUD",
+		"VHPTL3UAP": "app-2T9KkC9CTwxjzRKQSSM1REmJ",
+	}
+	apikey := apikeyMap[*req.AvatarId]
+	if apikey == "" {
+		return nil, fmt.Errorf("未知虚拟人id")
+	}
+
+	conversationId, err := l.GetConversation(apikey, strconv.FormatUint(*req.UserId, 10))
+	if conversationId == nil || err != nil {
+		return nil, err
+	}
+
+	baseURL, err := url.Parse("https://api.gptbots.ai/v1/conversation/message")
+	if err != nil {
+		return nil, errorx.NewDefaultError(fmt.Sprintf("生成内容失败: %+v", err))
+	}
+
+	// 构建请求体
+	requestBody := map[string]string{
+		"text":            *req.Text,
+		"conversation_id": *conversationId,
+		"response_mode":   "blocking",
+	}
+	jsonBody, err := json.Marshal(requestBody)
+	if err != nil {
+		return nil, errorx.NewDefaultError(fmt.Sprintf("生成内容失败: %+v", err))
+	}
+
+	// 创建HTTP请求
+	httpReq, err := http.NewRequest("POST", baseURL.String(), bytes.NewBuffer(jsonBody))
+	if err != nil {
+		return nil, errorx.NewDefaultError(fmt.Sprintf("生成内容失败: %+v", err))
+	}
+
+	// 添加必要的Header信息
+	httpReq.Header.Set("Authorization", fmt.Sprintf("Bearer %s", apikey))
+	httpReq.Header.Set("Content-Type", "application/json")
+
+	// 创建HTTP客户端并执行请求
+	client := &http.Client{}
+	response, err := client.Do(httpReq)
+	if err != nil {
+		return nil, errorx.NewDefaultError(fmt.Sprintf("生成内容失败: %+v", err))
+	}
+	defer func(Body io.ReadCloser) {
+		err := Body.Close()
+		if err != nil {
+			l.Error("生成内容失败: %v", err)
+		}
+	}(response.Body)
+
+	// 读取和输出响应
+	body, err := io.ReadAll(response.Body)
+	if err != nil {
+		return nil, errorx.NewDefaultError(fmt.Sprintf("生成内容失败: %+v", err))
+	}
+
+	// 检查响应状态
+	if response.StatusCode != http.StatusOK {
+		//log.Fatalf("请求失败,状态码:%d,响应: %s", response.StatusCode, string(body))
+		return nil, errorx.NewDefaultError(fmt.Sprintf("生成内容失败:%d,响应: %s", response.StatusCode, string(body)))
+	}
+
+	// 解析 JSON 响应
+	var responseMap types.GptbotsMessageResp
+	if err := json.Unmarshal(body, &responseMap); err != nil {
+		return nil, errorx.NewDefaultError(fmt.Sprintf("生成内容失败: %+v", err))
+	}
+
+	data := ""
+	if responseMap.FlowOutput != nil && len(responseMap.FlowOutput) > 0 {
+		data = TrimHtml(Markdown2Html(responseMap.FlowOutput[0].Content))
+	}
+
+	return &types.BaseDataInfo{Msg: errormsg.Success, Data: data}, nil
+}
+
+func (l *GptbotsChatLogic) GetConversation(apikey string, userId string) (conversationId *string, err error) {
+	val, _ := l.svcCtx.Rds.HGet(l.ctx, "xiaoice_conversation", userId).Result()
+	if val == "" {
+		baseURL, err := url.Parse("https://api.gptbots.ai/v1/conversation")
+		if err != nil {
+			return nil, err
+		}
+
+		// 构建请求体
+		requestBody := map[string]string{
+			"user_id": userId,
+		}
+		jsonBody, err := json.Marshal(requestBody)
+		if err != nil {
+			return nil, err
+		}
+
+		// 创建HTTP请求
+		req, err := http.NewRequest("POST", baseURL.String(), bytes.NewBuffer(jsonBody))
+		if err != nil {
+			return nil, err
+		}
+
+		// 添加必要的Header信息
+		req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", apikey))
+		req.Header.Set("Content-Type", "application/json")
+
+		// 创建HTTP客户端并执行请求
+		client := &http.Client{}
+		response, err := client.Do(req)
+		if err != nil {
+			return nil, err
+		}
+		defer func(Body io.ReadCloser) {
+			err := Body.Close()
+			if err != nil {
+				l.Error("创建会话失败败: %v", err)
+			}
+		}(response.Body)
+
+		// 读取和输出响应
+		body, err := io.ReadAll(response.Body)
+		if err != nil {
+			return nil, err
+		}
+
+		// 检查响应状态
+		if response.StatusCode != http.StatusOK {
+			//log.Fatalf("请求失败,状态码:%d,响应: %s", response.StatusCode, string(body))
+			return nil, errorx.NewDefaultError(fmt.Sprintf("创建会话失败:%d,响应: %s", response.StatusCode, string(body)))
+		}
+
+		// 解析 JSON 响应
+		var responseMap types.ConversationResp
+		if err := json.Unmarshal(body, &responseMap); err != nil {
+			return nil, err
+		}
+		l.svcCtx.Rds.HSet(l.ctx, "xiaoice_conversation", userId, *responseMap.ConversationId)
+		return responseMap.ConversationId, nil
+	}
+	return &val, nil
+}

+ 101 - 8
internal/types/types.go

@@ -389,6 +389,30 @@ type WxListReq struct {
 	Callback *string `json:"callback,optional"`
 }
 
+// Get wx list request params | Wx列表请求参数
+// swagger:model WxSelectListReq
+type WxSelectListReq struct {
+	// 租户id
+	OrganizationId *uint64 `json:"organizationId,optional"`
+}
+
+// The response data of wx list | Wx列表数据
+// swagger:model WxSelectListResp
+type WxSelectListResp struct {
+	BaseDataInfo
+	// Wx list data | Wx列表数据
+	Data []WxSelectListInfo `json:"data"`
+}
+
+// swagger:model WxSelectListInfo
+type WxSelectListInfo struct {
+	BaseIDInfo
+	// 微信id
+	Wxid *string `json:"wxid,optional"`
+	// 微信昵称
+	Nickname *string `json:"nickname,optional"`
+}
+
 // Wx information response | Wx信息返回体
 // swagger:model WxInfoResp
 type WxInfoResp struct {
@@ -1104,6 +1128,55 @@ type LabelSelectListInfo struct {
 	Value *uint64 `json:"value,optional"`
 }
 
+// The data of label tagging information | LabelTagging信息
+// swagger:model LabelTaggingInfo
+type LabelTaggingInfo struct {
+	BaseIDInfo
+	// Status 1: normal 2: ban | 状态 1 正常 2 禁用
+	Status *uint8 `json:"status,optional"`
+	// 机构 ID
+	OrganizationId *uint64 `json:"organizationId,optional"`
+	// 标签类型:1好友,2群组,3公众号,4企业微信联系人
+	Type *int `json:"type,optional"`
+	// 关键词
+	Conditions string `json:"conditions,optional"`
+	// 命中后需要打的标签
+	ActionLabelAdd []uint64 `json:"actionLabelAdd,optional"`
+	// 命中后需要移除的标签
+	ActionLabelDel []uint64 `json:"actionLabelDel,optional"`
+	LabelAddInfo   []string `json:"labelAddInfo,optional"`
+}
+
+// The response data of label tagging list | LabelTagging信息列表数据
+// swagger:model LabelTaggingListResp
+type LabelTaggingListResp struct {
+	BaseDataInfo
+	// The label tagging list data | LabelTagging信息列表数据
+	Data LabelTaggingListInfo `json:"data"`
+}
+
+// The label tagging list data | LabelTagging信息列表数据
+// swagger:model LabelTaggingListInfo
+type LabelTaggingListInfo struct {
+	BaseListInfo
+	// The label tagging list data | LabelTagging信息列表数据
+	Data []LabelTaggingInfo `json:"data"`
+}
+
+// Get label tagging list request params | LabelTagging信息列表请求参数
+// swagger:model LabelTaggingListReq
+type LabelTaggingListReq struct {
+	PageInfo
+}
+
+// The label tagging information response | LabelTagging信息返回体
+// swagger:model LabelTaggingInfoResp
+type LabelTaggingInfoResp struct {
+	BaseDataInfo
+	// label tagging information | LabelTagging信息数据
+	Data LabelTaggingInfo `json:"data"`
+}
+
 // The response data of sop task list | SopTask列表数据
 // swagger:model SopTaskListResp
 type SopTaskListResp struct {
@@ -1427,6 +1500,12 @@ type SopStageMoveReq struct {
 	Offset *int `json:"offset,optional"`
 }
 
+// swagger:model StageCopyReq
+type StageCopyReq struct {
+	// SopStage id | SopStage id
+	Id uint64 `json:"id"`
+}
+
 // The response data of sop node list | SopNode列表数据
 // swagger:model SopNodeListResp
 type SopNodeListResp struct {
@@ -3068,6 +3147,14 @@ type MessageReq struct {
 	Text   *string `json:"text"`
 }
 
+// swagger:model ChatReq
+type ChatReq struct {
+	// 大模型生成内容
+	AvatarId *string `json:"avatar_id"`
+	UserId   *uint64 `json:"user_id"`
+	Text     *string `json:"text"`
+}
+
 // swagger:model DashboardInfo
 type DashboardInfo struct {
 	BaseIDInfo
@@ -3079,6 +3166,7 @@ type ChartsReq struct {
 	EndDate   *string `json:"end_date"`
 	// 租户id
 	OrganizationId *uint64 `json:"organizationId,optional"`
+	Wxid           *string `json:"wxid,optional"`
 }
 
 // swagger:model ChartsResp
@@ -3100,17 +3188,21 @@ type ChartsData struct {
 }
 
 type ChartsUint struct {
-	Count uint64   `json:"count"`
-	Rate  float32  `json:"rate"`
-	Label []string `json:"label"`
-	Val   []uint64 `json:"val"`
+	Count     uint64   `json:"count"`
+	Rate      *float32 `json:"rate"`
+	Label     []string `json:"label"`
+	Val       []uint64 `json:"val"`
+	LabelText string   `json:"labelText"`
+	Tip       *string  `json:"tip"`
 }
 
 type ChartsInt struct {
-	Count int64    `json:"count"`
-	Rate  float32  `json:"rate"`
-	Label []string `json:"label"`
-	Val   []int64  `json:"val"`
+	Count     int64    `json:"count"`
+	Rate      *float32 `json:"rate"`
+	Label     []string `json:"label"`
+	Val       []int64  `json:"val"`
+	LabelText string   `json:"labelText"`
+	Tip       *string  `json:"tip"`
 }
 
 type LabelsData struct {
@@ -3124,6 +3216,7 @@ type WxReq struct {
 	EndDate *string `json:"end_date"`
 	// 租户id
 	OrganizationId *uint64 `json:"organizationId,optional"`
+	Wxid           *string `json:"wxid,optional"`
 }
 
 // swagger:model WxResp