Ver código fonte

Merge branch 'yhg_20250327'

jimmyyem 5 dias atrás
pai
commit
eed79b01b8
100 arquivos alterados com 12704 adições e 295 exclusões
  1. 0 1
      .gitignore
  2. 26 3
      crontask/compute_statistic.go
  3. 98 52
      crontask/contact_form.go
  4. 1 0
      crontask/init.go
  5. 4 1
      crontask/send_msg.go
  6. 4 1
      crontask/send_wx.go
  7. 3 0
      desc/all.api
  8. 11 0
      desc/openapi/chat.api
  9. 1 0
      desc/wechat/auth_login.api
  10. 2 0
      desc/wechat/contact.api
  11. 5 3
      desc/wechat/credit_balance.api
  12. 10 4
      desc/wechat/credit_usage.api
  13. 10 0
      desc/wechat/dashboard.api
  14. 8 0
      desc/wechat/usage_detail.api
  15. 1 1
      desc/wechat/user.api
  16. 96 0
      desc/wechat/xunji.api
  17. 92 0
      desc/wechat/xunji_service.api
  18. 26 0
      desc/wp_wecom/send_msg.api
  19. 18 2
      ent/agent.go
  20. 30 0
      ent/agent/agent.go
  21. 23 0
      ent/agent/where.go
  22. 32 0
      ent/agent_create.go
  23. 75 1
      ent/agent_query.go
  24. 163 0
      ent/agent_update.go
  25. 324 4
      ent/client.go
  26. 3 3
      ent/creditbalance.go
  27. 9 9
      ent/creditbalance/where.go
  28. 8 8
      ent/creditbalance_create.go
  29. 10 10
      ent/creditbalance_update.go
  30. 48 4
      ent/creditusage.go
  31. 34 0
      ent/creditusage/creditusage.go
  32. 229 9
      ent/creditusage/where.go
  33. 404 8
      ent/creditusage_create.go
  34. 298 10
      ent/creditusage_update.go
  35. 4 0
      ent/ent.go
  36. 24 0
      ent/hook/hook.go
  37. 60 0
      ent/intercept/intercept.go
  38. 87 3
      ent/migrate/schema.go
  39. 666 23
      ent/mutation.go
  40. 164 0
      ent/pagination.go
  41. 6 0
      ent/predicate/predicate.go
  42. 98 6
      ent/runtime/runtime.go
  43. 1 0
      ent/schema/agent.go
  44. 1 1
      ent/schema/credit_balance.go
  45. 5 1
      ent/schema/credit_usage.go
  46. 4 0
      ent/schema/usage_detail.go
  47. 1 0
      ent/schema/usage_statistic_day.go
  48. 1 0
      ent/schema/usage_statistic_hour.go
  49. 1 0
      ent/schema/usage_statistic_month.go
  50. 51 0
      ent/schema/xunji.go
  51. 60 0
      ent/schema/xunji_service.go
  52. 630 6
      ent/set_not_nil.go
  53. 6 0
      ent/tx.go
  54. 26 2
      ent/usagedetail.go
  55. 18 0
      ent/usagedetail/usagedetail.go
  56. 135 0
      ent/usagedetail/where.go
  57. 180 0
      ent/usagedetail_create.go
  58. 124 0
      ent/usagedetail_update.go
  59. 14 1
      ent/usagestatisticday.go
  60. 10 0
      ent/usagestatisticday/usagestatisticday.go
  61. 55 0
      ent/usagestatisticday/where.go
  62. 102 0
      ent/usagestatisticday_create.go
  63. 72 0
      ent/usagestatisticday_update.go
  64. 14 1
      ent/usagestatistichour.go
  65. 10 0
      ent/usagestatistichour/usagestatistichour.go
  66. 55 0
      ent/usagestatistichour/where.go
  67. 102 0
      ent/usagestatistichour_create.go
  68. 72 0
      ent/usagestatistichour_update.go
  69. 14 1
      ent/usagestatisticmonth.go
  70. 10 0
      ent/usagestatisticmonth/usagestatisticmonth.go
  71. 55 0
      ent/usagestatisticmonth/where.go
  72. 102 0
      ent/usagestatisticmonth_create.go
  73. 72 0
      ent/usagestatisticmonth_update.go
  74. 194 0
      ent/xunji.go
  75. 635 0
      ent/xunji/where.go
  76. 134 0
      ent/xunji/xunji.go
  77. 1113 0
      ent/xunji_create.go
  78. 88 0
      ent/xunji_delete.go
  79. 526 0
      ent/xunji_query.go
  80. 636 0
      ent/xunji_update.go
  81. 234 0
      ent/xunjiservice.go
  82. 639 0
      ent/xunjiservice/where.go
  83. 172 0
      ent/xunjiservice/xunjiservice.go
  84. 1178 0
      ent/xunjiservice_create.go
  85. 88 0
      ent/xunjiservice_delete.go
  86. 605 0
      ent/xunjiservice_query.go
  87. 735 0
      ent/xunjiservice_update.go
  88. 0 101
      etc/wechat.yaml
  89. 2 10
      go.mod
  90. 0 2
      go.sum
  91. 113 0
      hook/credit/credit.go
  92. 79 0
      hook/credit/models.go
  93. 3 1
      hook/message.go
  94. 0 1
      internal/handler/auth/login_handler.go
  95. 31 0
      internal/handler/auth/logout_handler.go
  96. 44 0
      internal/handler/chat/send_text_msg_handler.go
  97. 105 1
      internal/handler/routes.go
  98. 44 0
      internal/handler/wp_wecom/send_msg_by_chan_handler.go
  99. 44 0
      internal/handler/wp_wecom/send_msg_handler.go
  100. 44 0
      internal/handler/xunji/create_xunji_handler.go

+ 0 - 1
.gitignore

@@ -33,6 +33,5 @@ vendor/
 wechat-api
 etc/wechat.yaml
 /etc/wechat.yaml
-
 cli/asynctask/etc/asynctask-prod.yaml
 cli/asynctask/wechat_api_open

+ 26 - 3
crontask/compute_statistic.go

@@ -55,13 +55,16 @@ func (l *CronTask) computeStatistic() {
 	lc := []custom_types.LabelDist{}
 
 	var allHourAiResponseInt, allHourSopRunInt, allHourFriendCountInt, allHourGroupCountInt, allHourAccountBalanceInt, allHourConsumeTokenInt, allHourActiveUserInt, allHourNewUserInt int
+	var allHourConsumeCoinFloat float64
 	for orgID, wxinfos := range wxbotsSet {
 		var orgAiResponseInt, orgSopRunInt, orgFriendCountInt, orgGroupCountInt, orgAccountBalanceInt, orgConsumeTokenInt, orgActiveUserInt, orgNewUserInt int
+		var orgHourConsumeCoinFloat float64
 		for _, wxinfo := range wxinfos {
 			l.Logger.Infof("开始计算小时数据:%d\n", lastHourInt)
 
 			// 先判断该账号是否已经统计了小时数据,如果已经统计了,就不需要再统计了
 			var aiResponseInt, sopRunInt, friendCountInt, groupCountInt, accountBalanceInt, consumeTokenInt, activeUserInt, newUserInt int
+			var consumeCoinFloat float64
 			hourDataCount, _ := l.svcCtx.DB.UsageStatisticHour.Query().Where(
 				usagestatistichour.Type(1),
 				usagestatistichour.BotID(wxinfo.Wxid),
@@ -123,7 +126,6 @@ func (l *CronTask) computeStatistic() {
 
 			// 消耗Token数:usage_detail 表
 			consumeTokenInt, _ = l.svcCtx.DB.UsageDetail.Query().Where(
-				usagedetail.TypeEQ(1),
 				usagedetail.BotID(wxinfo.Wxid),
 				usagedetail.CreatedAtGTE(lastHour),
 				usagedetail.CreatedAtLT(currentHour),
@@ -131,6 +133,15 @@ func (l *CronTask) computeStatistic() {
 			orgConsumeTokenInt += consumeTokenInt
 			allHourConsumeTokenInt += consumeTokenInt
 
+			// 计算积分消耗
+			consumeCoinFloat, _ = l.svcCtx.DB.UsageDetail.Query().Where(
+				usagedetail.BotID(wxinfo.Wxid),
+				usagedetail.CreatedAtGTE(lastHour),
+				usagedetail.CreatedAtLT(currentHour),
+			).Aggregate(ent.Sum("credits")).Float64(l.ctx)
+			allHourConsumeCoinFloat += consumeCoinFloat
+			orgHourConsumeCoinFloat += consumeCoinFloat
+
 			// 账户余额
 			accountBalanceInt = 0
 			orgAccountBalanceInt = 0
@@ -138,7 +149,7 @@ func (l *CronTask) computeStatistic() {
 
 			// 活跃好友:usage_detail 表 type = 1
 			activeUsers, _ := l.svcCtx.DB.UsageDetail.Query().Where(
-				usagedetail.Type(1),
+				usagedetail.TypeIn(1, 6),
 				usagedetail.BotID(wxinfo.Wxid),
 				usagedetail.CreatedAtGTE(lastHour),
 				usagedetail.CreatedAtLT(currentHour),
@@ -171,6 +182,7 @@ func (l *CronTask) computeStatistic() {
 				SetTotalGroup(uint64(groupCountInt)).
 				SetAccountBalance(uint64(accountBalanceInt)).
 				SetConsumeToken(uint64(consumeTokenInt)).
+				SetConsumeCoin(consumeCoinFloat).
 				SetActiveUser(uint64(activeUserInt)).
 				SetNewUser(int64(newUserInt)).
 				SetAddtime(uint64(lastHourInt)).
@@ -205,6 +217,7 @@ func (l *CronTask) computeStatistic() {
 			SetTotalGroup(uint64(orgGroupCountInt)).
 			SetAccountBalance(uint64(orgAccountBalanceInt)).
 			SetConsumeToken(uint64(orgConsumeTokenInt)).
+			SetConsumeCoin(orgHourConsumeCoinFloat).
 			SetActiveUser(uint64(orgActiveUserInt)).
 			SetNewUser(int64(orgNewUserInt)).
 			SetAddtime(uint64(lastHourInt)).
@@ -230,6 +243,7 @@ func (l *CronTask) computeStatistic() {
 			SetTotalGroup(uint64(allHourGroupCountInt)).
 			SetAccountBalance(uint64(allHourAccountBalanceInt)).
 			SetConsumeToken(uint64(allHourConsumeTokenInt)).
+			SetConsumeCoin(allHourConsumeCoinFloat).
 			SetActiveUser(uint64(allHourActiveUserInt)).
 			SetNewUser(int64(allHourNewUserInt)).
 			SetAddtime(uint64(lastHourInt)).
@@ -257,9 +271,11 @@ func (l *CronTask) computeStatistic() {
 
 	var allDayAiResponseInt, allDaySopRunInt, allDayFriendCountInt, allDayGroupCountInt, allDayAccountBalanceInt, allDayConsumeTokenInt, allDayActiveUserInt uint64
 	var allDayNewUserInt int64
+	var allDayConsumeCoinFloat float64
 	for orgID, wxinfos := range wxbotsSet {
 		var orgAiResponseInt, orgSopRunInt, orgFriendCountInt, orgGroupCountInt, orgAccountBalanceInt, orgConsumeTokenInt, orgActiveUserInt uint64
 		var orgNewUserInt int64
+		var orgDayConsumeCoinFloat float64
 		for _, wxinfo := range wxinfos {
 			l.Logger.Infof("开始计算日数据:%d\n", yesterdayInt)
 
@@ -275,6 +291,7 @@ func (l *CronTask) computeStatistic() {
 			}
 			var aiResponse, sopRun, totalFriend, totalGroup, accountBalance, consumeToken, activeUser uint64
 			var newUser int64
+			var consumeCoin float64
 			for _, hourData := range hourDataBatch {
 				aiResponse += hourData.AiResponse
 				sopRun += hourData.SopRun
@@ -284,11 +301,12 @@ func (l *CronTask) computeStatistic() {
 				consumeToken += hourData.ConsumeToken
 				//activeUser += hourData.ActiveUser
 				newUser += hourData.NewUser
+				consumeCoin += hourData.ConsumeCoin
 			}
 
 			// 活跃好友:usage_detail 表 type = 1
 			activeUsers, _ := l.svcCtx.DB.UsageDetail.Query().Where(
-				usagedetail.Type(1),
+				usagedetail.TypeIn(1, 6),
 				usagedetail.BotID(wxinfo.Wxid),
 				usagedetail.CreatedAtGTE(yesterdayFirstHour),
 				usagedetail.CreatedAtLT(yesterdayLastHour),
@@ -303,6 +321,7 @@ func (l *CronTask) computeStatistic() {
 			orgConsumeTokenInt += consumeToken
 			orgActiveUserInt += activeUser
 			orgNewUserInt += newUser
+			orgDayConsumeCoinFloat += consumeCoin
 
 			allDayAiResponseInt += aiResponse
 			allDaySopRunInt += sopRun
@@ -312,6 +331,7 @@ func (l *CronTask) computeStatistic() {
 			allDayConsumeTokenInt += consumeToken
 			allDayActiveUserInt += activeUser
 			allDayNewUserInt += newUser
+			allDayConsumeCoinFloat += consumeCoin
 
 			// 先判断该账号是否已经统计了日数据,如果已经统计了,就不需要再统计了
 			dayDataCount, _ := l.svcCtx.DB.UsageStatisticDay.Query().Where(
@@ -333,6 +353,7 @@ func (l *CronTask) computeStatistic() {
 					SetTotalGroup(totalGroup).
 					SetAccountBalance(accountBalance).
 					SetConsumeToken(consumeToken).
+					SetConsumeCoin(consumeCoin).
 					SetActiveUser(activeUser).
 					SetNewUser(newUser).
 					SetLabelDist(lc).
@@ -363,6 +384,7 @@ func (l *CronTask) computeStatistic() {
 				SetTotalGroup(orgGroupCountInt).
 				SetAccountBalance(orgAccountBalanceInt).
 				SetConsumeToken(orgConsumeTokenInt).
+				SetConsumeCoin(orgDayConsumeCoinFloat).
 				SetActiveUser(orgActiveUserInt).
 				SetNewUser(orgNewUserInt).
 				SetNotNilLabelDist(LabelsCountSet[orgID]).
@@ -394,6 +416,7 @@ func (l *CronTask) computeStatistic() {
 			SetTotalGroup(allDayGroupCountInt).
 			SetAccountBalance(allDayAccountBalanceInt).
 			SetConsumeToken(allDayConsumeTokenInt).
+			SetConsumeCoin(allDayConsumeCoinFloat).
 			SetActiveUser(allDayActiveUserInt).
 			SetNewUser(allDayNewUserInt).
 			SetLabelDist(lc).

+ 98 - 52
crontask/contact_form.go

@@ -1,12 +1,10 @@
 package crontask
 
 import (
-	"bytes"
 	"encoding/json"
 	"fmt"
 	"github.com/google/uuid"
 	"github.com/zeromicro/go-zero/core/logx"
-	"net/http"
 	"strconv"
 	"time"
 	"wechat-api/ent/contact"
@@ -15,6 +13,8 @@ import (
 	"wechat-api/ent/custom_types"
 	"wechat-api/ent/predicate"
 	"wechat-api/ent/usagedetail"
+	"wechat-api/internal/types"
+	"wechat-api/internal/utils/compapi"
 )
 
 type ResponseItem struct {
@@ -126,15 +126,15 @@ func (l *CronTask) analyze() {
 	var predicates []predicate.UsageDetail
 	predicates = append(predicates, usagedetail.TypeIn(1, 3))
 	predicates = append(predicates, usagedetail.AppIn(1, 3, 4, 5))
-	yesterdayStart := time.Now().AddDate(0, 0, -1).Truncate(24 * time.Hour)
-	yesterdayEnd := yesterdayStart.Add(24 * time.Hour)
-	predicates = append(predicates, usagedetail.CreatedAtGTE(yesterdayStart))
-	predicates = append(predicates, usagedetail.CreatedAtLT(yesterdayEnd))
+	//yesterdayStart := time.Now().AddDate(0, 0, -1).Truncate(24 * time.Hour)
+	//yesterdayEnd := yesterdayStart.Add(24 * time.Hour)
+	//predicates = append(predicates, usagedetail.CreatedAtGTE(yesterdayStart))
+	//predicates = append(predicates, usagedetail.CreatedAtLT(yesterdayEnd))
 
-	//todayStart := time.Now().AddDate(0, 0, 0).Truncate(24 * time.Hour)
-	//todayEnd := todayStart.Add(24 * time.Hour)
-	//predicates = append(predicates, usagedetail.CreatedAtGTE(todayStart))
-	//predicates = append(predicates, usagedetail.CreatedAtLT(todayEnd))
+	todayStart := time.Now().AddDate(0, 0, 0).Truncate(24 * time.Hour)
+	todayEnd := todayStart.Add(24 * time.Hour)
+	predicates = append(predicates, usagedetail.CreatedAtGTE(todayStart))
+	predicates = append(predicates, usagedetail.CreatedAtLT(todayEnd))
 
 	data, err := l.svcCtx.DB.UsageDetail.Query().Where(predicates...).All(l.ctx)
 	logx.Info("usageDetails: ", data)
@@ -168,7 +168,7 @@ func (l *CronTask) analyze() {
 			template = append(template, contactBasicFieldTemplates...)
 		}
 		for receiverID, messages := range usageDetails[botID] {
-			result, _ := openaiRequest(messages, template)
+			result, _ := l.openaiRequest(messages, template)
 			logx.Info("result: ", result)
 			if result == nil {
 				continue
@@ -179,53 +179,99 @@ func (l *CronTask) analyze() {
 
 }
 
-func openaiRequest(messages string, template []custom_types.ContactFieldTemplate) ([]ResponseItem, error) {
-	url := "https://toolsapi-debug.gkscrm.com/call_center/form/extract"
-	bodyData := map[string]interface{}{
-		"form_data":    ConvertFormData(template),
-		"chat_history": messages,
-		"external_id":  uuid.New().String(),
-	}
-	logx.Info("bodyData: %+v", bodyData)
-	bodyBytes, err := json.Marshal(bodyData)
-	if err != nil {
-		return nil, err
-	}
-
-	req, err := http.NewRequest("POST", url, bytes.NewBuffer(bodyBytes))
-	if err != nil {
-		return nil, err
-	}
-	req.Header.Set("Content-Type", "application/json")
-	req.Header.Set("Authorization", "Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxIn0.ZS9jnsLPCnmc8L_lu4yaQFp34vwWF1mHlHSBYrY5JVs")
-
-	client := &http.Client{}
-	resp, err := client.Do(req)
-	if err != nil || resp == nil || resp.Body == nil {
-		logx.Error("read body error: ", err)
-		return nil, err
-	}
-
-	logx.Info("err: ", err)
+func (l *CronTask) openaiRequest(messages string, template []custom_types.ContactFieldTemplate) ([]ResponseItem, error) {
+	formData := ConvertFormData(template)
+	jsonBytes, err := json.Marshal(formData)
 	if err != nil {
 		return nil, err
 	}
-	defer resp.Body.Close()
-
-	if resp.StatusCode != http.StatusOK {
-		return nil, fmt.Errorf("unexpected status code: %d", resp.StatusCode)
-	}
-
-	//var result []ResponseItem
-	var fullResp struct {
-		Data []ResponseItem `json:"data"`
+	jsonStr := string(jsonBytes)
+	req := &types.CompApiReq{
+		types.CompCtlReq{
+			"form",
+			"",
+			false,
+			"",
+		},
+		types.StdCompApiReq{
+			"gpt-4o",
+			[]types.StdCompMessage{},
+			false,
+			nil,
+		},
+		types.FastGptSpecReq{
+			"",
+			"",
+			"",
+			false,
+			map[string]string{
+				"form_data":    jsonStr,
+				"chat_history": messages,
+				"external_id":  uuid.New().String(),
+			},
+		},
 	}
-	err = json.NewDecoder(resp.Body).Decode(&fullResp)
-	if err != nil {
+	resp, err := compapi.NewClient(l.ctx, compapi.WithApiBase("http://new-api.gkscrm.com/v1/"),
+		compapi.WithApiKey("sk-wwttAtdLcTfeF7F2Eb9d3592Bd4c487f8e8fA544D6C4BbA9")).
+		Chat(req)
+	if err == nil && resp != nil && len(resp.Choices) > 0 {
+		//logx.Info("resp.Choices: ", resp.Choices[0].Message.Content)
+		var items []ResponseItem
+		err = json.Unmarshal([]byte(resp.Choices[0].Message.Content), &items)
+		if err != nil {
+			return nil, err
+		}
+		return items, nil
+	} else if resp != nil && len(resp.Choices) == 0 {
 		return nil, err
 	}
-
-	return fullResp.Data, nil
+	//url := "https://toolsapi-debug.gkscrm.com/call_center/form/extract"
+	//bodyData := map[string]interface{}{
+	//	"form_data":    ConvertFormData(template),
+	//	"chat_history": messages,
+	//	"external_id":  uuid.New().String(),
+	//}
+	//logx.Info("bodyData: %+v", bodyData)
+	//bodyBytes, err := json.Marshal(bodyData)
+	//if err != nil {
+	//	return nil, err
+	//}
+	//
+	//req, err := http.NewRequest("POST", url, bytes.NewBuffer(bodyBytes))
+	//if err != nil {
+	//	return nil, err
+	//}
+	//req.Header.Set("Content-Type", "application/json")
+	//req.Header.Set("Authorization", "Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxIn0.ZS9jnsLPCnmc8L_lu4yaQFp34vwWF1mHlHSBYrY5JVs")
+	//
+	//client := &http.Client{}
+	//resp, err := client.Do(req)
+	//if err != nil || resp == nil || resp.Body == nil {
+	//	logx.Error("read body error: ", err)
+	//	return nil, err
+	//}
+	//
+	//logx.Info("err: ", err)
+	//if err != nil {
+	//	return nil, err
+	//}
+	//defer resp.Body.Close()
+	//
+	//if resp.StatusCode != http.StatusOK {
+	//	return nil, fmt.Errorf("unexpected status code: %d", resp.StatusCode)
+	//}
+	//
+	////var result []ResponseItem
+	//var fullResp struct {
+	//	Data []ResponseItem `json:"data"`
+	//}
+	//err = json.NewDecoder(resp.Body).Decode(&fullResp)
+	//if err != nil {
+	//	return nil, err
+	//}
+	//
+	//return fullResp.Data, nil
+	return nil, err
 }
 
 func (l *CronTask) UpdateContactFields(botID string, receiverID string, fields []ResponseItem) error {

+ 1 - 0
crontask/init.go

@@ -60,4 +60,5 @@ func ScheduleRun(c *cron.Cron, serverCtx *svc.ServiceContext) {
 	//	MaxChannel := 3
 	//	l.compApiCallback(MaxWorker, MaxChannel)
 	//})
+
 }

+ 4 - 1
crontask/send_msg.go

@@ -2,6 +2,7 @@ package crontask
 
 import (
 	"encoding/json"
+	"fmt"
 	"net/url"
 	"path"
 	"time"
@@ -224,7 +225,9 @@ func (l *CronTask) sendMsg() {
 			// 这里之前只有文字消息(既 msgtype=1) 目前增加了图片 所以增加了msgtype=2
 			// 所以增加了一个判断,判断发送的内容类型,如果是文字就调用SendTextMsg,如果是图片就调用SendPicMsg
 			if msg.Msgtype == 1 {
-				err = hookClient.SendTextMsg(msg.Toid, msg.Msg, wxInfo.Wxid)
+				msgId := time.Now().UnixNano() / int64(time.Microsecond)
+				l.svcCtx.Rds.Set(l.ctx, fmt.Sprintf("MsgId_FriendId:%d", msgId), msg.Toid, 10*time.Minute)
+				err = hookClient.SendTextMsg(msg.Toid, msg.Msg, wxInfo.Wxid, msgId)
 			} else if msg.Msgtype == 2 {
 				diyfilename := getFileName(msg.Msg)
 				err = hookClient.SendPicMsg(msg.Toid, msg.Msg, diyfilename, wxInfo.Wxid)

+ 4 - 1
crontask/send_wx.go

@@ -3,6 +3,7 @@ package crontask
 import (
 	"context"
 	"encoding/json"
+	"fmt"
 	"regexp"
 	"strconv"
 	"strings"
@@ -144,7 +145,9 @@ func (l *CronTask) sendWx() {
 					contactInfo, _ := getContactInfo(v.BotWxid, v.ContactWxid)
 					content = varReplace(content, contactInfo)
 				}
-				err = hookClient.SendTextMsg(v.ContactWxid, content, v.BotWxid)
+				msgId := time.Now().UnixNano() / int64(time.Microsecond)
+				l.svcCtx.Rds.Set(l.ctx, fmt.Sprintf("MsgId_FriendId:%d", msgId), v.ContactWxid, 10*time.Minute)
+				err = hookClient.SendTextMsg(v.ContactWxid, content, v.BotWxid, msgId)
 			} else {
 				re := regexp.MustCompile(`[^/]+$`)
 				fileName := re.FindString(v.Content)

+ 3 - 0
desc/all.api

@@ -43,6 +43,9 @@ import "./wechat/credit_usage.api"
 import "./wechat/pay_recharge.api"
 import "./wechat/whatsapp.api"
 import "./wechat/whatsapp_channel.api"
+import "./wechat/xunji.api"
+import "./wechat/xunji_service.api"
+import "./wp_wecom/send_msg.api"
 import "./wechat/fastgpt.api"
 import "./wechat/department.api"
 import "./wechat/api_key.api"

+ 11 - 0
desc/openapi/chat.api

@@ -210,3 +210,14 @@ service Wechat {
     @handler chatCompletions
     post /chat/completions (CompApiReq) returns (CompOpenApiResp)
 }
+
+@server(
+	
+    group: chat
+    middleware: OpenAuthority
+)
+
+service Wechat {
+	@handler sendTextMsg
+	post /wx/sendTextMsg (SendTextMsgReq) returns (BaseMsgResp)
+}	

+ 1 - 0
desc/wechat/auth_login.api

@@ -81,3 +81,4 @@ service Wechat {
     post /user/login_by_sms (LoginBySmsReq) returns (LoginResp)
 
 }
+

+ 2 - 0
desc/wechat/contact.api

@@ -67,6 +67,8 @@ type (
 
 		//标签搜索开始结束日期
 		SearchDate []*string `json:"date,optional"`
+
+        Status *uint8 `json:"status,optional"`
     }
 
     // Contact information response | Contact信息返回体

+ 5 - 3
desc/wechat/credit_balance.api

@@ -6,10 +6,10 @@ type (
         BaseIDInfo
 
         // user_id | 用户ID 
-        UserId  *string `json:"userId,optional"`
+//        UserId  *string `json:"userId,optional"`
 
         // role | 角色设定 
-        Balance  *float32 `json:"balance,optional"`
+        Balance  *float64 `json:"balance,optional"`
 
         // status | 状态 1-正常 2-禁用 
         Status  *int `json:"status,optional"`
@@ -55,7 +55,9 @@ type (
 
 	CreditBalanceOperateReq {
 		OrganizationId  *uint64 `json:"organizationId,optional"`
-		Number  *float32 `json:"number,optional"`
+		Number  *float64 `json:"number,optional"`
+		PayNumber *float64 `json:"payNumber,optional"`
+		PayMethod *int `json:"payMethod,optional"`
 		Reason *string `json:"reason,optional"`
 	}
 )

+ 10 - 4
desc/wechat/credit_usage.api

@@ -5,12 +5,15 @@ type (
     CreditUsageInfo {
         BaseIDInfo
 
-        // user_id | 用户ID 
-        UserId  *string `json:"userId,optional"`
-		UserInfo UserInfo `json:"userInfo,optional"`
+        // user_id | 用户ID
+//        UserId  *string `json:"userId,optional"`
 
         // number | 积分改变量 
-        Number  *float32 `json:"number,optional"`
+        Number  *float64 `json:"number,optional"`
+		BeforeNumber *float64 `json:"beforeNumber,optional"`
+		AfterNumber *float64 `json:"afterNumber,optional"`
+		PayNumber  *float64 `json:"payNumber,optional"`
+		PayMethod *int `json:"payMethod,optional"`
 
         // status | 状态 1-正常 2-禁用 
         Status  *int `json:"status,optional"`
@@ -33,6 +36,7 @@ type (
 
         // operator | 积分变动人 
         Operator  *string `json:"operator,optional"`
+		OperatorName *string `json:"operatorName,optional"`
     }
 
     // The response data of credit usage list | CreditUsage列表数据
@@ -56,6 +60,8 @@ type (
         PageInfo
 
 		OrganizationId  *uint64 `json:"organizationId,optional"`
+		Ntype  *int `json:"ntype,optional"`
+		SearchDate []string `json:"searchDate,optional"`
     }
 
     // CreditUsage information response | CreditUsage信息返回体

+ 10 - 0
desc/wechat/dashboard.api

@@ -31,6 +31,7 @@ type (
         ActiveUser *ChartsUint `json:"active_user"`
         NewUser *ChartsInt `json:"new_user"`
         LabelDist []LabelsData `json:"label_dist"`
+		ConsumeCoin *ChartsFloat `json:"consume_coin"`
     }
 
     ChartsUint {
@@ -42,6 +43,15 @@ type (
         Tip *string `json:"tip"`
     }
 
+	ChartsFloat {
+		Count float64 `json:"count"`
+		Rate *float32 `json:"rate"`
+		Label []string `json:"label"`
+		Val []float64 `json:"val"`
+		LabelText string `json:"labelText"`
+		Tip *string `json:"tip"`
+	}
+
     ChartsInt {
         Count int64 `json:"count"`
         Rate *float32 `json:"rate"`

+ 8 - 0
desc/wechat/usage_detail.api

@@ -40,6 +40,10 @@ type (
 
         // 组织ID
         OrganizationId *uint64 `json:"organizationId,optional"`
+		OrganizationName *string `json:"organizationName,optional"`
+
+		Model *string `json:"model,optional"`
+		Credits  *float64 `json:"credits,optional"`
     }
 
     // The response data of UsageDetail list | UsageDetail列表数据
@@ -63,7 +67,11 @@ type (
         PageInfo
 
         // 租户id
+		OrganizationId *uint64 `json:"organizationId,optional"`
+		Type *int `json:"type,optional"`
         BotId  *string `json:"botId,optional"`
+		ReceiverId  *string `json:"receiverId,optional"`
+		SearchDate []string `json:"searchDate,optional"`
     }
 
 	UsageDetailResp {

+ 1 - 1
desc/wechat/user.api

@@ -141,7 +141,7 @@ type (
 		Data BalanceInfo `json:"data"`
 	}
 	BalanceInfo {
-		Balance *float32 `json:"balance"`
+		Balance *float64 `json:"balance"`
 	}
 )
 

+ 96 - 0
desc/wechat/xunji.api

@@ -0,0 +1,96 @@
+import "../base.api"
+
+type (
+    // The data of xunji information | Xunji信息
+    XunjiInfo {
+        BaseIDInfo
+
+        // Status 1: normal 2: ban | 状态 1 正常 2 禁用 
+        Status  *uint8 `json:"status,optional"`
+
+        // AppKey 
+        AppKey  *string `json:"appKey,optional"`
+
+        // AppSecret 
+        AppSecret  *string `json:"appSecret,optional"`
+
+        // Token 
+        Token  *string `json:"token,optional"`
+
+        // 加密key 
+        EncodingKey  *string `json:"encodingKey,optional"`
+
+        // organization_id | 租户ID 
+        OrganizationId  *uint64 `json:"organizationId,optional"`
+    }
+
+    // The response data of xunji list | Xunji列表数据
+    XunjiListResp {
+        BaseDataInfo
+
+        // Xunji list data | Xunji列表数据
+        Data XunjiListInfo `json:"data"`
+    }
+
+    // Xunji list data | Xunji列表数据
+    XunjiListInfo {
+        BaseListInfo
+
+        // The API list data | Xunji列表数据
+        Data  []XunjiInfo  `json:"data"`
+    }
+
+    // Get xunji list request params | Xunji列表请求参数
+    XunjiListReq {
+        PageInfo
+
+        // AppKey 
+        AppKey  *string `json:"appKey,optional"`
+
+        // AppSecret 
+        AppSecret  *string `json:"appSecret,optional"`
+
+        // Token 
+        Token  *string `json:"token,optional"`
+    }
+
+    // Xunji information response | Xunji信息返回体
+    XunjiInfoResp {
+        BaseDataInfo
+
+        // Xunji information | Xunji数据
+        Data XunjiInfo `json:"data"`
+    }
+)
+
+@server(
+    jwt: Auth
+    group: xunji
+    middleware: Authority
+)
+
+service Wechat {
+    // Create xunji information | 创建Xunji
+    @handler createXunji
+    post /xunji/create (XunjiInfo) returns (BaseMsgResp)
+
+    // Update xunji information | 更新Xunji
+    @handler updateXunji
+    post /xunji/update (XunjiInfo) returns (BaseMsgResp)
+
+    // Delete xunji information | 删除Xunji信息
+    @handler deleteXunji
+    post /xunji/delete (IDsReq) returns (BaseMsgResp)
+
+    // Get xunji list | 获取Xunji列表
+    @handler getXunjiList
+    post /xunji/list (XunjiListReq) returns (XunjiListResp)
+
+    // Get xunji by ID | 通过ID获取Xunji
+    @handler getXunjiById
+    post /xunji (IDReq) returns (XunjiInfoResp)
+
+	// Get xunji  | 通过机构ID获取Xunji
+	@handler getXunji
+	post /xunji/detail () returns (XunjiInfoResp)
+}

+ 92 - 0
desc/wechat/xunji_service.api

@@ -0,0 +1,92 @@
+import "../base.api"
+import "./agent.api"
+
+type (
+    // The data of xunji service information | XunjiService信息
+    XunjiServiceInfo {
+        BaseIDInfo
+
+        // Status 1: normal 2: ban | 状态 1 正常 2 禁用 
+        Status  *uint8 `json:"status,optional"`
+
+        // Xunji表ID 
+        XunjiId  *uint64 `json:"xunjiId,optional"`
+
+        // 智能体ID 
+        AgentId  *uint64 `json:"agentId,optional"`
+
+		// 模式信息
+		AgentInfo *AgentInfo `json:"agentInfo,optional"`
+
+        // organization_id | 租户ID 
+        OrganizationId  *uint64 `json:"organizationId,optional"`
+
+        // 微信ID 
+        Wxid  *string `json:"wxid,optional"`
+
+        // 大模型服务地址 
+        ApiBase  *string `json:"apiBase,optional"`
+
+        // 大模型服务密钥 
+        ApiKey  *string `json:"apiKey,optional"`
+    }
+
+    // The response data of xunji service list | XunjiService列表数据
+    XunjiServiceListResp {
+        BaseDataInfo
+
+        // XunjiService list data | XunjiService列表数据
+        Data XunjiServiceListInfo `json:"data"`
+    }
+
+    // XunjiService list data | XunjiService列表数据
+    XunjiServiceListInfo {
+        BaseListInfo
+
+        // The API list data | XunjiService列表数据
+        Data  []XunjiServiceInfo  `json:"data"`
+    }
+
+    // Get xunji service list request params | XunjiService列表请求参数
+    XunjiServiceListReq {
+        PageInfo
+
+        XunjiID *uint64 `json:"configId,optional"`
+    }
+
+    // XunjiService information response | XunjiService信息返回体
+    XunjiServiceInfoResp {
+        BaseDataInfo
+
+        // XunjiService information | XunjiService数据
+        Data XunjiServiceInfo `json:"data"`
+    }
+)
+
+@server(
+    jwt: Auth
+    group: xunji_service
+    middleware: Authority
+)
+
+service Wechat {
+    // Create xunji service information | 创建XunjiService
+    @handler createXunjiService
+    post /xunji_service/create (XunjiServiceInfo) returns (BaseMsgResp)
+
+    // Update xunji service information | 更新XunjiService
+    @handler updateXunjiService
+    post /xunji_service/update (XunjiServiceInfo) returns (BaseMsgResp)
+
+    // Delete xunji service information | 删除XunjiService信息
+    @handler deleteXunjiService
+    post /xunji_service/delete (IDsReq) returns (BaseMsgResp)
+
+    // Get xunji service list | 获取XunjiService列表
+    @handler getXunjiServiceList
+    post /xunji_service/list (XunjiServiceListReq) returns (XunjiServiceListResp)
+
+    // Get xunji service by ID | 通过ID获取XunjiService
+    @handler getXunjiServiceById
+    post /xunji_service (IDReq) returns (XunjiServiceInfoResp)
+}

+ 26 - 0
desc/wp_wecom/send_msg.api

@@ -0,0 +1,26 @@
+import "../base.api"
+
+type (
+    WpWecomMsgReq {
+        // 机器人微信id
+        WxId *string `json:"wx_id"`
+        // 接收方微信 id
+        ConvId *string `json:"conv_id"`
+        // 消息类型
+        ContentType *string `json:"content_type"`
+        // 消息内容
+        Content *string `json:"content"`
+    }
+)
+
+@server(
+	group: wp_wecom
+)
+
+service Wechat {
+    @handler sendMsg
+    post /wp/wecom/send_msg (WpWecomMsgReq) returns (BaseMsgResp)
+
+    @handler sendMsgByChan
+    post /wp/wecom/send_msg_by_chan (WpWecomMsgReq) returns (BaseMsgResp)
+}

+ 18 - 2
ent/agent.go

@@ -61,11 +61,13 @@ type AgentEdges struct {
 	TokenAgent []*Token `json:"token_agent,omitempty"`
 	// WaAgent holds the value of the wa_agent edge.
 	WaAgent []*Whatsapp `json:"wa_agent,omitempty"`
+	// XjsAgent holds the value of the xjs_agent edge.
+	XjsAgent []*XunjiService `json:"xjs_agent,omitempty"`
 	// KeyAgent holds the value of the key_agent edge.
 	KeyAgent []*ApiKey `json:"key_agent,omitempty"`
 	// loadedTypes holds the information for reporting if a
 	// type was loaded (or requested) in eager-loading or not.
-	loadedTypes [4]bool
+	loadedTypes [5]bool
 }
 
 // WxAgentOrErr returns the WxAgent value or an error if the edge
@@ -95,10 +97,19 @@ func (e AgentEdges) WaAgentOrErr() ([]*Whatsapp, error) {
 	return nil, &NotLoadedError{edge: "wa_agent"}
 }
 
+// XjsAgentOrErr returns the XjsAgent value or an error if the edge
+// was not loaded in eager-loading.
+func (e AgentEdges) XjsAgentOrErr() ([]*XunjiService, error) {
+	if e.loadedTypes[3] {
+		return e.XjsAgent, nil
+	}
+	return nil, &NotLoadedError{edge: "xjs_agent"}
+}
+
 // KeyAgentOrErr returns the KeyAgent value or an error if the edge
 // was not loaded in eager-loading.
 func (e AgentEdges) KeyAgentOrErr() ([]*ApiKey, error) {
-	if e.loadedTypes[3] {
+	if e.loadedTypes[4] {
 		return e.KeyAgent, nil
 	}
 	return nil, &NotLoadedError{edge: "key_agent"}
@@ -254,6 +265,11 @@ func (a *Agent) QueryWaAgent() *WhatsappQuery {
 	return NewAgentClient(a.config).QueryWaAgent(a)
 }
 
+// QueryXjsAgent queries the "xjs_agent" edge of the Agent entity.
+func (a *Agent) QueryXjsAgent() *XunjiServiceQuery {
+	return NewAgentClient(a.config).QueryXjsAgent(a)
+}
+
 // QueryKeyAgent queries the "key_agent" edge of the Agent entity.
 func (a *Agent) QueryKeyAgent() *ApiKeyQuery {
 	return NewAgentClient(a.config).QueryKeyAgent(a)

+ 30 - 0
ent/agent/agent.go

@@ -51,6 +51,8 @@ const (
 	EdgeTokenAgent = "token_agent"
 	// EdgeWaAgent holds the string denoting the wa_agent edge name in mutations.
 	EdgeWaAgent = "wa_agent"
+	// EdgeXjsAgent holds the string denoting the xjs_agent edge name in mutations.
+	EdgeXjsAgent = "xjs_agent"
 	// EdgeKeyAgent holds the string denoting the key_agent edge name in mutations.
 	EdgeKeyAgent = "key_agent"
 	// Table holds the table name of the agent in the database.
@@ -76,6 +78,13 @@ const (
 	WaAgentInverseTable = "whatsapp"
 	// WaAgentColumn is the table column denoting the wa_agent relation/edge.
 	WaAgentColumn = "agent_id"
+	// XjsAgentTable is the table that holds the xjs_agent relation/edge.
+	XjsAgentTable = "xunji_service"
+	// XjsAgentInverseTable is the table name for the XunjiService entity.
+	// It exists in this package in order to avoid circular dependency with the "xunjiservice" package.
+	XjsAgentInverseTable = "xunji_service"
+	// XjsAgentColumn is the table column denoting the xjs_agent relation/edge.
+	XjsAgentColumn = "agent_id"
 	// KeyAgentTable is the table that holds the key_agent relation/edge.
 	KeyAgentTable = "api_key"
 	// KeyAgentInverseTable is the table name for the ApiKey entity.
@@ -288,6 +297,20 @@ func ByWaAgent(term sql.OrderTerm, terms ...sql.OrderTerm) OrderOption {
 	}
 }
 
+// ByXjsAgentCount orders the results by xjs_agent count.
+func ByXjsAgentCount(opts ...sql.OrderTermOption) OrderOption {
+	return func(s *sql.Selector) {
+		sqlgraph.OrderByNeighborsCount(s, newXjsAgentStep(), opts...)
+	}
+}
+
+// ByXjsAgent orders the results by xjs_agent terms.
+func ByXjsAgent(term sql.OrderTerm, terms ...sql.OrderTerm) OrderOption {
+	return func(s *sql.Selector) {
+		sqlgraph.OrderByNeighborTerms(s, newXjsAgentStep(), append([]sql.OrderTerm{term}, terms...)...)
+	}
+}
+
 // ByKeyAgentCount orders the results by key_agent count.
 func ByKeyAgentCount(opts ...sql.OrderTermOption) OrderOption {
 	return func(s *sql.Selector) {
@@ -322,6 +345,13 @@ func newWaAgentStep() *sqlgraph.Step {
 		sqlgraph.Edge(sqlgraph.O2M, false, WaAgentTable, WaAgentColumn),
 	)
 }
+func newXjsAgentStep() *sqlgraph.Step {
+	return sqlgraph.NewStep(
+		sqlgraph.From(Table, FieldID),
+		sqlgraph.To(XjsAgentInverseTable, FieldID),
+		sqlgraph.Edge(sqlgraph.O2M, false, XjsAgentTable, XjsAgentColumn),
+	)
+}
 func newKeyAgentStep() *sqlgraph.Step {
 	return sqlgraph.NewStep(
 		sqlgraph.From(Table, FieldID),

+ 23 - 0
ent/agent/where.go

@@ -1114,6 +1114,29 @@ func HasWaAgentWith(preds ...predicate.Whatsapp) predicate.Agent {
 	})
 }
 
+// HasXjsAgent applies the HasEdge predicate on the "xjs_agent" edge.
+func HasXjsAgent() predicate.Agent {
+	return predicate.Agent(func(s *sql.Selector) {
+		step := sqlgraph.NewStep(
+			sqlgraph.From(Table, FieldID),
+			sqlgraph.Edge(sqlgraph.O2M, false, XjsAgentTable, XjsAgentColumn),
+		)
+		sqlgraph.HasNeighbors(s, step)
+	})
+}
+
+// HasXjsAgentWith applies the HasEdge predicate on the "xjs_agent" edge with a given conditions (other predicates).
+func HasXjsAgentWith(preds ...predicate.XunjiService) predicate.Agent {
+	return predicate.Agent(func(s *sql.Selector) {
+		step := newXjsAgentStep()
+		sqlgraph.HasNeighborsWith(s, step, func(s *sql.Selector) {
+			for _, p := range preds {
+				p(s)
+			}
+		})
+	})
+}
+
 // HasKeyAgent applies the HasEdge predicate on the "key_agent" edge.
 func HasKeyAgent() predicate.Agent {
 	return predicate.Agent(func(s *sql.Selector) {

+ 32 - 0
ent/agent_create.go

@@ -12,6 +12,7 @@ import (
 	"wechat-api/ent/token"
 	"wechat-api/ent/whatsapp"
 	"wechat-api/ent/wx"
+	"wechat-api/ent/xunjiservice"
 
 	"entgo.io/ent/dialect/sql"
 	"entgo.io/ent/dialect/sql/sqlgraph"
@@ -271,6 +272,21 @@ func (ac *AgentCreate) AddWaAgent(w ...*Whatsapp) *AgentCreate {
 	return ac.AddWaAgentIDs(ids...)
 }
 
+// AddXjsAgentIDs adds the "xjs_agent" edge to the XunjiService entity by IDs.
+func (ac *AgentCreate) AddXjsAgentIDs(ids ...uint64) *AgentCreate {
+	ac.mutation.AddXjsAgentIDs(ids...)
+	return ac
+}
+
+// AddXjsAgent adds the "xjs_agent" edges to the XunjiService entity.
+func (ac *AgentCreate) AddXjsAgent(x ...*XunjiService) *AgentCreate {
+	ids := make([]uint64, len(x))
+	for i := range x {
+		ids[i] = x[i].ID
+	}
+	return ac.AddXjsAgentIDs(ids...)
+}
+
 // AddKeyAgentIDs adds the "key_agent" edge to the ApiKey entity by IDs.
 func (ac *AgentCreate) AddKeyAgentIDs(ids ...uint64) *AgentCreate {
 	ac.mutation.AddKeyAgentIDs(ids...)
@@ -571,6 +587,22 @@ func (ac *AgentCreate) createSpec() (*Agent, *sqlgraph.CreateSpec) {
 		}
 		_spec.Edges = append(_spec.Edges, edge)
 	}
+	if nodes := ac.mutation.XjsAgentIDs(); len(nodes) > 0 {
+		edge := &sqlgraph.EdgeSpec{
+			Rel:     sqlgraph.O2M,
+			Inverse: false,
+			Table:   agent.XjsAgentTable,
+			Columns: []string{agent.XjsAgentColumn},
+			Bidi:    false,
+			Target: &sqlgraph.EdgeTarget{
+				IDSpec: sqlgraph.NewFieldSpec(xunjiservice.FieldID, field.TypeUint64),
+			},
+		}
+		for _, k := range nodes {
+			edge.Target.Nodes = append(edge.Target.Nodes, k)
+		}
+		_spec.Edges = append(_spec.Edges, edge)
+	}
 	if nodes := ac.mutation.KeyAgentIDs(); len(nodes) > 0 {
 		edge := &sqlgraph.EdgeSpec{
 			Rel:     sqlgraph.O2M,

+ 75 - 1
ent/agent_query.go

@@ -13,6 +13,7 @@ import (
 	"wechat-api/ent/token"
 	"wechat-api/ent/whatsapp"
 	"wechat-api/ent/wx"
+	"wechat-api/ent/xunjiservice"
 
 	"entgo.io/ent/dialect/sql"
 	"entgo.io/ent/dialect/sql/sqlgraph"
@@ -29,6 +30,7 @@ type AgentQuery struct {
 	withWxAgent    *WxQuery
 	withTokenAgent *TokenQuery
 	withWaAgent    *WhatsappQuery
+	withXjsAgent   *XunjiServiceQuery
 	withKeyAgent   *ApiKeyQuery
 	// intermediate query (i.e. traversal path).
 	sql  *sql.Selector
@@ -132,6 +134,28 @@ func (aq *AgentQuery) QueryWaAgent() *WhatsappQuery {
 	return query
 }
 
+// QueryXjsAgent chains the current query on the "xjs_agent" edge.
+func (aq *AgentQuery) QueryXjsAgent() *XunjiServiceQuery {
+	query := (&XunjiServiceClient{config: aq.config}).Query()
+	query.path = func(ctx context.Context) (fromU *sql.Selector, err error) {
+		if err := aq.prepareQuery(ctx); err != nil {
+			return nil, err
+		}
+		selector := aq.sqlQuery(ctx)
+		if err := selector.Err(); err != nil {
+			return nil, err
+		}
+		step := sqlgraph.NewStep(
+			sqlgraph.From(agent.Table, agent.FieldID, selector),
+			sqlgraph.To(xunjiservice.Table, xunjiservice.FieldID),
+			sqlgraph.Edge(sqlgraph.O2M, false, agent.XjsAgentTable, agent.XjsAgentColumn),
+		)
+		fromU = sqlgraph.SetNeighbors(aq.driver.Dialect(), step)
+		return fromU, nil
+	}
+	return query
+}
+
 // QueryKeyAgent chains the current query on the "key_agent" edge.
 func (aq *AgentQuery) QueryKeyAgent() *ApiKeyQuery {
 	query := (&ApiKeyClient{config: aq.config}).Query()
@@ -349,6 +373,7 @@ func (aq *AgentQuery) Clone() *AgentQuery {
 		withWxAgent:    aq.withWxAgent.Clone(),
 		withTokenAgent: aq.withTokenAgent.Clone(),
 		withWaAgent:    aq.withWaAgent.Clone(),
+		withXjsAgent:   aq.withXjsAgent.Clone(),
 		withKeyAgent:   aq.withKeyAgent.Clone(),
 		// clone intermediate query.
 		sql:  aq.sql.Clone(),
@@ -389,6 +414,17 @@ func (aq *AgentQuery) WithWaAgent(opts ...func(*WhatsappQuery)) *AgentQuery {
 	return aq
 }
 
+// WithXjsAgent tells the query-builder to eager-load the nodes that are connected to
+// the "xjs_agent" edge. The optional arguments are used to configure the query builder of the edge.
+func (aq *AgentQuery) WithXjsAgent(opts ...func(*XunjiServiceQuery)) *AgentQuery {
+	query := (&XunjiServiceClient{config: aq.config}).Query()
+	for _, opt := range opts {
+		opt(query)
+	}
+	aq.withXjsAgent = query
+	return aq
+}
+
 // WithKeyAgent tells the query-builder to eager-load the nodes that are connected to
 // the "key_agent" edge. The optional arguments are used to configure the query builder of the edge.
 func (aq *AgentQuery) WithKeyAgent(opts ...func(*ApiKeyQuery)) *AgentQuery {
@@ -478,10 +514,11 @@ func (aq *AgentQuery) sqlAll(ctx context.Context, hooks ...queryHook) ([]*Agent,
 	var (
 		nodes       = []*Agent{}
 		_spec       = aq.querySpec()
-		loadedTypes = [4]bool{
+		loadedTypes = [5]bool{
 			aq.withWxAgent != nil,
 			aq.withTokenAgent != nil,
 			aq.withWaAgent != nil,
+			aq.withXjsAgent != nil,
 			aq.withKeyAgent != nil,
 		}
 	)
@@ -524,6 +561,13 @@ func (aq *AgentQuery) sqlAll(ctx context.Context, hooks ...queryHook) ([]*Agent,
 			return nil, err
 		}
 	}
+	if query := aq.withXjsAgent; query != nil {
+		if err := aq.loadXjsAgent(ctx, query, nodes,
+			func(n *Agent) { n.Edges.XjsAgent = []*XunjiService{} },
+			func(n *Agent, e *XunjiService) { n.Edges.XjsAgent = append(n.Edges.XjsAgent, e) }); err != nil {
+			return nil, err
+		}
+	}
 	if query := aq.withKeyAgent; query != nil {
 		if err := aq.loadKeyAgent(ctx, query, nodes,
 			func(n *Agent) { n.Edges.KeyAgent = []*ApiKey{} },
@@ -625,6 +669,36 @@ func (aq *AgentQuery) loadWaAgent(ctx context.Context, query *WhatsappQuery, nod
 	}
 	return nil
 }
+func (aq *AgentQuery) loadXjsAgent(ctx context.Context, query *XunjiServiceQuery, nodes []*Agent, init func(*Agent), assign func(*Agent, *XunjiService)) error {
+	fks := make([]driver.Value, 0, len(nodes))
+	nodeids := make(map[uint64]*Agent)
+	for i := range nodes {
+		fks = append(fks, nodes[i].ID)
+		nodeids[nodes[i].ID] = nodes[i]
+		if init != nil {
+			init(nodes[i])
+		}
+	}
+	if len(query.ctx.Fields) > 0 {
+		query.ctx.AppendFieldOnce(xunjiservice.FieldAgentID)
+	}
+	query.Where(predicate.XunjiService(func(s *sql.Selector) {
+		s.Where(sql.InValues(s.C(agent.XjsAgentColumn), fks...))
+	}))
+	neighbors, err := query.All(ctx)
+	if err != nil {
+		return err
+	}
+	for _, n := range neighbors {
+		fk := n.AgentID
+		node, ok := nodeids[fk]
+		if !ok {
+			return fmt.Errorf(`unexpected referenced foreign-key "agent_id" returned %v for node %v`, fk, n.ID)
+		}
+		assign(node, n)
+	}
+	return nil
+}
 func (aq *AgentQuery) loadKeyAgent(ctx context.Context, query *ApiKeyQuery, nodes []*Agent, init func(*Agent), assign func(*Agent, *ApiKey)) error {
 	fks := make([]driver.Value, 0, len(nodes))
 	nodeids := make(map[uint64]*Agent)

+ 163 - 0
ent/agent_update.go

@@ -13,6 +13,7 @@ import (
 	"wechat-api/ent/token"
 	"wechat-api/ent/whatsapp"
 	"wechat-api/ent/wx"
+	"wechat-api/ent/xunjiservice"
 
 	"entgo.io/ent/dialect/sql"
 	"entgo.io/ent/dialect/sql/sqlgraph"
@@ -340,6 +341,21 @@ func (au *AgentUpdate) AddWaAgent(w ...*Whatsapp) *AgentUpdate {
 	return au.AddWaAgentIDs(ids...)
 }
 
+// AddXjsAgentIDs adds the "xjs_agent" edge to the XunjiService entity by IDs.
+func (au *AgentUpdate) AddXjsAgentIDs(ids ...uint64) *AgentUpdate {
+	au.mutation.AddXjsAgentIDs(ids...)
+	return au
+}
+
+// AddXjsAgent adds the "xjs_agent" edges to the XunjiService entity.
+func (au *AgentUpdate) AddXjsAgent(x ...*XunjiService) *AgentUpdate {
+	ids := make([]uint64, len(x))
+	for i := range x {
+		ids[i] = x[i].ID
+	}
+	return au.AddXjsAgentIDs(ids...)
+}
+
 // AddKeyAgentIDs adds the "key_agent" edge to the ApiKey entity by IDs.
 func (au *AgentUpdate) AddKeyAgentIDs(ids ...uint64) *AgentUpdate {
 	au.mutation.AddKeyAgentIDs(ids...)
@@ -423,6 +439,27 @@ func (au *AgentUpdate) RemoveWaAgent(w ...*Whatsapp) *AgentUpdate {
 	return au.RemoveWaAgentIDs(ids...)
 }
 
+// ClearXjsAgent clears all "xjs_agent" edges to the XunjiService entity.
+func (au *AgentUpdate) ClearXjsAgent() *AgentUpdate {
+	au.mutation.ClearXjsAgent()
+	return au
+}
+
+// RemoveXjsAgentIDs removes the "xjs_agent" edge to XunjiService entities by IDs.
+func (au *AgentUpdate) RemoveXjsAgentIDs(ids ...uint64) *AgentUpdate {
+	au.mutation.RemoveXjsAgentIDs(ids...)
+	return au
+}
+
+// RemoveXjsAgent removes "xjs_agent" edges to XunjiService entities.
+func (au *AgentUpdate) RemoveXjsAgent(x ...*XunjiService) *AgentUpdate {
+	ids := make([]uint64, len(x))
+	for i := range x {
+		ids[i] = x[i].ID
+	}
+	return au.RemoveXjsAgentIDs(ids...)
+}
+
 // ClearKeyAgent clears all "key_agent" edges to the ApiKey entity.
 func (au *AgentUpdate) ClearKeyAgent() *AgentUpdate {
 	au.mutation.ClearKeyAgent()
@@ -746,6 +783,51 @@ func (au *AgentUpdate) sqlSave(ctx context.Context) (n int, err error) {
 		}
 		_spec.Edges.Add = append(_spec.Edges.Add, edge)
 	}
+	if au.mutation.XjsAgentCleared() {
+		edge := &sqlgraph.EdgeSpec{
+			Rel:     sqlgraph.O2M,
+			Inverse: false,
+			Table:   agent.XjsAgentTable,
+			Columns: []string{agent.XjsAgentColumn},
+			Bidi:    false,
+			Target: &sqlgraph.EdgeTarget{
+				IDSpec: sqlgraph.NewFieldSpec(xunjiservice.FieldID, field.TypeUint64),
+			},
+		}
+		_spec.Edges.Clear = append(_spec.Edges.Clear, edge)
+	}
+	if nodes := au.mutation.RemovedXjsAgentIDs(); len(nodes) > 0 && !au.mutation.XjsAgentCleared() {
+		edge := &sqlgraph.EdgeSpec{
+			Rel:     sqlgraph.O2M,
+			Inverse: false,
+			Table:   agent.XjsAgentTable,
+			Columns: []string{agent.XjsAgentColumn},
+			Bidi:    false,
+			Target: &sqlgraph.EdgeTarget{
+				IDSpec: sqlgraph.NewFieldSpec(xunjiservice.FieldID, field.TypeUint64),
+			},
+		}
+		for _, k := range nodes {
+			edge.Target.Nodes = append(edge.Target.Nodes, k)
+		}
+		_spec.Edges.Clear = append(_spec.Edges.Clear, edge)
+	}
+	if nodes := au.mutation.XjsAgentIDs(); len(nodes) > 0 {
+		edge := &sqlgraph.EdgeSpec{
+			Rel:     sqlgraph.O2M,
+			Inverse: false,
+			Table:   agent.XjsAgentTable,
+			Columns: []string{agent.XjsAgentColumn},
+			Bidi:    false,
+			Target: &sqlgraph.EdgeTarget{
+				IDSpec: sqlgraph.NewFieldSpec(xunjiservice.FieldID, field.TypeUint64),
+			},
+		}
+		for _, k := range nodes {
+			edge.Target.Nodes = append(edge.Target.Nodes, k)
+		}
+		_spec.Edges.Add = append(_spec.Edges.Add, edge)
+	}
 	if au.mutation.KeyAgentCleared() {
 		edge := &sqlgraph.EdgeSpec{
 			Rel:     sqlgraph.O2M,
@@ -1119,6 +1201,21 @@ func (auo *AgentUpdateOne) AddWaAgent(w ...*Whatsapp) *AgentUpdateOne {
 	return auo.AddWaAgentIDs(ids...)
 }
 
+// AddXjsAgentIDs adds the "xjs_agent" edge to the XunjiService entity by IDs.
+func (auo *AgentUpdateOne) AddXjsAgentIDs(ids ...uint64) *AgentUpdateOne {
+	auo.mutation.AddXjsAgentIDs(ids...)
+	return auo
+}
+
+// AddXjsAgent adds the "xjs_agent" edges to the XunjiService entity.
+func (auo *AgentUpdateOne) AddXjsAgent(x ...*XunjiService) *AgentUpdateOne {
+	ids := make([]uint64, len(x))
+	for i := range x {
+		ids[i] = x[i].ID
+	}
+	return auo.AddXjsAgentIDs(ids...)
+}
+
 // AddKeyAgentIDs adds the "key_agent" edge to the ApiKey entity by IDs.
 func (auo *AgentUpdateOne) AddKeyAgentIDs(ids ...uint64) *AgentUpdateOne {
 	auo.mutation.AddKeyAgentIDs(ids...)
@@ -1202,6 +1299,27 @@ func (auo *AgentUpdateOne) RemoveWaAgent(w ...*Whatsapp) *AgentUpdateOne {
 	return auo.RemoveWaAgentIDs(ids...)
 }
 
+// ClearXjsAgent clears all "xjs_agent" edges to the XunjiService entity.
+func (auo *AgentUpdateOne) ClearXjsAgent() *AgentUpdateOne {
+	auo.mutation.ClearXjsAgent()
+	return auo
+}
+
+// RemoveXjsAgentIDs removes the "xjs_agent" edge to XunjiService entities by IDs.
+func (auo *AgentUpdateOne) RemoveXjsAgentIDs(ids ...uint64) *AgentUpdateOne {
+	auo.mutation.RemoveXjsAgentIDs(ids...)
+	return auo
+}
+
+// RemoveXjsAgent removes "xjs_agent" edges to XunjiService entities.
+func (auo *AgentUpdateOne) RemoveXjsAgent(x ...*XunjiService) *AgentUpdateOne {
+	ids := make([]uint64, len(x))
+	for i := range x {
+		ids[i] = x[i].ID
+	}
+	return auo.RemoveXjsAgentIDs(ids...)
+}
+
 // ClearKeyAgent clears all "key_agent" edges to the ApiKey entity.
 func (auo *AgentUpdateOne) ClearKeyAgent() *AgentUpdateOne {
 	auo.mutation.ClearKeyAgent()
@@ -1555,6 +1673,51 @@ func (auo *AgentUpdateOne) sqlSave(ctx context.Context) (_node *Agent, err error
 		}
 		_spec.Edges.Add = append(_spec.Edges.Add, edge)
 	}
+	if auo.mutation.XjsAgentCleared() {
+		edge := &sqlgraph.EdgeSpec{
+			Rel:     sqlgraph.O2M,
+			Inverse: false,
+			Table:   agent.XjsAgentTable,
+			Columns: []string{agent.XjsAgentColumn},
+			Bidi:    false,
+			Target: &sqlgraph.EdgeTarget{
+				IDSpec: sqlgraph.NewFieldSpec(xunjiservice.FieldID, field.TypeUint64),
+			},
+		}
+		_spec.Edges.Clear = append(_spec.Edges.Clear, edge)
+	}
+	if nodes := auo.mutation.RemovedXjsAgentIDs(); len(nodes) > 0 && !auo.mutation.XjsAgentCleared() {
+		edge := &sqlgraph.EdgeSpec{
+			Rel:     sqlgraph.O2M,
+			Inverse: false,
+			Table:   agent.XjsAgentTable,
+			Columns: []string{agent.XjsAgentColumn},
+			Bidi:    false,
+			Target: &sqlgraph.EdgeTarget{
+				IDSpec: sqlgraph.NewFieldSpec(xunjiservice.FieldID, field.TypeUint64),
+			},
+		}
+		for _, k := range nodes {
+			edge.Target.Nodes = append(edge.Target.Nodes, k)
+		}
+		_spec.Edges.Clear = append(_spec.Edges.Clear, edge)
+	}
+	if nodes := auo.mutation.XjsAgentIDs(); len(nodes) > 0 {
+		edge := &sqlgraph.EdgeSpec{
+			Rel:     sqlgraph.O2M,
+			Inverse: false,
+			Table:   agent.XjsAgentTable,
+			Columns: []string{agent.XjsAgentColumn},
+			Bidi:    false,
+			Target: &sqlgraph.EdgeTarget{
+				IDSpec: sqlgraph.NewFieldSpec(xunjiservice.FieldID, field.TypeUint64),
+			},
+		}
+		for _, k := range nodes {
+			edge.Target.Nodes = append(edge.Target.Nodes, k)
+		}
+		_spec.Edges.Add = append(_spec.Edges.Add, edge)
+	}
 	if auo.mutation.KeyAgentCleared() {
 		edge := &sqlgraph.EdgeSpec{
 			Rel:     sqlgraph.O2M,

+ 324 - 4
ent/client.go

@@ -56,6 +56,8 @@ import (
 	"wechat-api/ent/wxcard"
 	"wechat-api/ent/wxcarduser"
 	"wechat-api/ent/wxcardvisit"
+	"wechat-api/ent/xunji"
+	"wechat-api/ent/xunjiservice"
 
 	"entgo.io/ent"
 	"entgo.io/ent/dialect"
@@ -160,6 +162,10 @@ type Client struct {
 	WxCardUser *WxCardUserClient
 	// WxCardVisit is the client for interacting with the WxCardVisit builders.
 	WxCardVisit *WxCardVisitClient
+	// Xunji is the client for interacting with the Xunji builders.
+	Xunji *XunjiClient
+	// XunjiService is the client for interacting with the XunjiService builders.
+	XunjiService *XunjiServiceClient
 }
 
 // NewClient creates a new client configured with the given options.
@@ -216,6 +222,8 @@ func (c *Client) init() {
 	c.WxCard = NewWxCardClient(c.config)
 	c.WxCardUser = NewWxCardUserClient(c.config)
 	c.WxCardVisit = NewWxCardVisitClient(c.config)
+	c.Xunji = NewXunjiClient(c.config)
+	c.XunjiService = NewXunjiServiceClient(c.config)
 }
 
 type (
@@ -353,6 +361,8 @@ func (c *Client) Tx(ctx context.Context) (*Tx, error) {
 		WxCard:               NewWxCardClient(cfg),
 		WxCardUser:           NewWxCardUserClient(cfg),
 		WxCardVisit:          NewWxCardVisitClient(cfg),
+		Xunji:                NewXunjiClient(cfg),
+		XunjiService:         NewXunjiServiceClient(cfg),
 	}, nil
 }
 
@@ -417,6 +427,8 @@ func (c *Client) BeginTx(ctx context.Context, opts *sql.TxOptions) (*Tx, error)
 		WxCard:               NewWxCardClient(cfg),
 		WxCardUser:           NewWxCardUserClient(cfg),
 		WxCardVisit:          NewWxCardVisitClient(cfg),
+		Xunji:                NewXunjiClient(cfg),
+		XunjiService:         NewXunjiServiceClient(cfg),
 	}, nil
 }
 
@@ -454,7 +466,8 @@ func (c *Client) Use(hooks ...Hook) {
 		c.SopNode, c.SopStage, c.SopTask, c.Token, c.Tutorial, c.UsageDetail,
 		c.UsageStatisticDay, c.UsageStatisticHour, c.UsageStatisticMonth, c.UsageTotal,
 		c.Whatsapp, c.WhatsappChannel, c.WorkExperience, c.WpChatroom,
-		c.WpChatroomMember, c.Wx, c.WxCard, c.WxCardUser, c.WxCardVisit,
+		c.WpChatroomMember, c.Wx, c.WxCard, c.WxCardUser, c.WxCardVisit, c.Xunji,
+		c.XunjiService,
 	} {
 		n.Use(hooks...)
 	}
@@ -472,7 +485,8 @@ func (c *Client) Intercept(interceptors ...Interceptor) {
 		c.SopNode, c.SopStage, c.SopTask, c.Token, c.Tutorial, c.UsageDetail,
 		c.UsageStatisticDay, c.UsageStatisticHour, c.UsageStatisticMonth, c.UsageTotal,
 		c.Whatsapp, c.WhatsappChannel, c.WorkExperience, c.WpChatroom,
-		c.WpChatroomMember, c.Wx, c.WxCard, c.WxCardUser, c.WxCardVisit,
+		c.WpChatroomMember, c.Wx, c.WxCard, c.WxCardUser, c.WxCardVisit, c.Xunji,
+		c.XunjiService,
 	} {
 		n.Intercept(interceptors...)
 	}
@@ -571,6 +585,10 @@ func (c *Client) Mutate(ctx context.Context, m Mutation) (Value, error) {
 		return c.WxCardUser.mutate(ctx, m)
 	case *WxCardVisitMutation:
 		return c.WxCardVisit.mutate(ctx, m)
+	case *XunjiMutation:
+		return c.Xunji.mutate(ctx, m)
+	case *XunjiServiceMutation:
+		return c.XunjiService.mutate(ctx, m)
 	default:
 		return nil, fmt.Errorf("ent: unknown mutation type %T", m)
 	}
@@ -732,6 +750,22 @@ func (c *AgentClient) QueryWaAgent(a *Agent) *WhatsappQuery {
 	return query
 }
 
+// QueryXjsAgent queries the xjs_agent edge of a Agent.
+func (c *AgentClient) QueryXjsAgent(a *Agent) *XunjiServiceQuery {
+	query := (&XunjiServiceClient{config: c.config}).Query()
+	query.path = func(context.Context) (fromV *sql.Selector, _ error) {
+		id := a.ID
+		step := sqlgraph.NewStep(
+			sqlgraph.From(agent.Table, agent.FieldID, id),
+			sqlgraph.To(xunjiservice.Table, xunjiservice.FieldID),
+			sqlgraph.Edge(sqlgraph.O2M, false, agent.XjsAgentTable, agent.XjsAgentColumn),
+		)
+		fromV = sqlgraph.Neighbors(a.driver.Dialect(), step)
+		return fromV, nil
+	}
+	return query
+}
+
 // QueryKeyAgent queries the key_agent edge of a Agent.
 func (c *AgentClient) QueryKeyAgent(a *Agent) *ApiKeyQuery {
 	query := (&ApiKeyClient{config: c.config}).Query()
@@ -7125,6 +7159,292 @@ func (c *WxCardVisitClient) mutate(ctx context.Context, m *WxCardVisitMutation)
 	}
 }
 
+// XunjiClient is a client for the Xunji schema.
+type XunjiClient struct {
+	config
+}
+
+// NewXunjiClient returns a client for the Xunji from the given config.
+func NewXunjiClient(c config) *XunjiClient {
+	return &XunjiClient{config: c}
+}
+
+// Use adds a list of mutation hooks to the hooks stack.
+// A call to `Use(f, g, h)` equals to `xunji.Hooks(f(g(h())))`.
+func (c *XunjiClient) Use(hooks ...Hook) {
+	c.hooks.Xunji = append(c.hooks.Xunji, hooks...)
+}
+
+// Intercept adds a list of query interceptors to the interceptors stack.
+// A call to `Intercept(f, g, h)` equals to `xunji.Intercept(f(g(h())))`.
+func (c *XunjiClient) Intercept(interceptors ...Interceptor) {
+	c.inters.Xunji = append(c.inters.Xunji, interceptors...)
+}
+
+// Create returns a builder for creating a Xunji entity.
+func (c *XunjiClient) Create() *XunjiCreate {
+	mutation := newXunjiMutation(c.config, OpCreate)
+	return &XunjiCreate{config: c.config, hooks: c.Hooks(), mutation: mutation}
+}
+
+// CreateBulk returns a builder for creating a bulk of Xunji entities.
+func (c *XunjiClient) CreateBulk(builders ...*XunjiCreate) *XunjiCreateBulk {
+	return &XunjiCreateBulk{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 *XunjiClient) MapCreateBulk(slice any, setFunc func(*XunjiCreate, int)) *XunjiCreateBulk {
+	rv := reflect.ValueOf(slice)
+	if rv.Kind() != reflect.Slice {
+		return &XunjiCreateBulk{err: fmt.Errorf("calling to XunjiClient.MapCreateBulk with wrong type %T, need slice", slice)}
+	}
+	builders := make([]*XunjiCreate, rv.Len())
+	for i := 0; i < rv.Len(); i++ {
+		builders[i] = c.Create()
+		setFunc(builders[i], i)
+	}
+	return &XunjiCreateBulk{config: c.config, builders: builders}
+}
+
+// Update returns an update builder for Xunji.
+func (c *XunjiClient) Update() *XunjiUpdate {
+	mutation := newXunjiMutation(c.config, OpUpdate)
+	return &XunjiUpdate{config: c.config, hooks: c.Hooks(), mutation: mutation}
+}
+
+// UpdateOne returns an update builder for the given entity.
+func (c *XunjiClient) UpdateOne(x *Xunji) *XunjiUpdateOne {
+	mutation := newXunjiMutation(c.config, OpUpdateOne, withXunji(x))
+	return &XunjiUpdateOne{config: c.config, hooks: c.Hooks(), mutation: mutation}
+}
+
+// UpdateOneID returns an update builder for the given id.
+func (c *XunjiClient) UpdateOneID(id uint64) *XunjiUpdateOne {
+	mutation := newXunjiMutation(c.config, OpUpdateOne, withXunjiID(id))
+	return &XunjiUpdateOne{config: c.config, hooks: c.Hooks(), mutation: mutation}
+}
+
+// Delete returns a delete builder for Xunji.
+func (c *XunjiClient) Delete() *XunjiDelete {
+	mutation := newXunjiMutation(c.config, OpDelete)
+	return &XunjiDelete{config: c.config, hooks: c.Hooks(), mutation: mutation}
+}
+
+// DeleteOne returns a builder for deleting the given entity.
+func (c *XunjiClient) DeleteOne(x *Xunji) *XunjiDeleteOne {
+	return c.DeleteOneID(x.ID)
+}
+
+// DeleteOneID returns a builder for deleting the given entity by its id.
+func (c *XunjiClient) DeleteOneID(id uint64) *XunjiDeleteOne {
+	builder := c.Delete().Where(xunji.ID(id))
+	builder.mutation.id = &id
+	builder.mutation.op = OpDeleteOne
+	return &XunjiDeleteOne{builder}
+}
+
+// Query returns a query builder for Xunji.
+func (c *XunjiClient) Query() *XunjiQuery {
+	return &XunjiQuery{
+		config: c.config,
+		ctx:    &QueryContext{Type: TypeXunji},
+		inters: c.Interceptors(),
+	}
+}
+
+// Get returns a Xunji entity by its id.
+func (c *XunjiClient) Get(ctx context.Context, id uint64) (*Xunji, error) {
+	return c.Query().Where(xunji.ID(id)).Only(ctx)
+}
+
+// GetX is like Get, but panics if an error occurs.
+func (c *XunjiClient) GetX(ctx context.Context, id uint64) *Xunji {
+	obj, err := c.Get(ctx, id)
+	if err != nil {
+		panic(err)
+	}
+	return obj
+}
+
+// Hooks returns the client hooks.
+func (c *XunjiClient) Hooks() []Hook {
+	hooks := c.hooks.Xunji
+	return append(hooks[:len(hooks):len(hooks)], xunji.Hooks[:]...)
+}
+
+// Interceptors returns the client interceptors.
+func (c *XunjiClient) Interceptors() []Interceptor {
+	inters := c.inters.Xunji
+	return append(inters[:len(inters):len(inters)], xunji.Interceptors[:]...)
+}
+
+func (c *XunjiClient) mutate(ctx context.Context, m *XunjiMutation) (Value, error) {
+	switch m.Op() {
+	case OpCreate:
+		return (&XunjiCreate{config: c.config, hooks: c.Hooks(), mutation: m}).Save(ctx)
+	case OpUpdate:
+		return (&XunjiUpdate{config: c.config, hooks: c.Hooks(), mutation: m}).Save(ctx)
+	case OpUpdateOne:
+		return (&XunjiUpdateOne{config: c.config, hooks: c.Hooks(), mutation: m}).Save(ctx)
+	case OpDelete, OpDeleteOne:
+		return (&XunjiDelete{config: c.config, hooks: c.Hooks(), mutation: m}).Exec(ctx)
+	default:
+		return nil, fmt.Errorf("ent: unknown Xunji mutation op: %q", m.Op())
+	}
+}
+
+// XunjiServiceClient is a client for the XunjiService schema.
+type XunjiServiceClient struct {
+	config
+}
+
+// NewXunjiServiceClient returns a client for the XunjiService from the given config.
+func NewXunjiServiceClient(c config) *XunjiServiceClient {
+	return &XunjiServiceClient{config: c}
+}
+
+// Use adds a list of mutation hooks to the hooks stack.
+// A call to `Use(f, g, h)` equals to `xunjiservice.Hooks(f(g(h())))`.
+func (c *XunjiServiceClient) Use(hooks ...Hook) {
+	c.hooks.XunjiService = append(c.hooks.XunjiService, hooks...)
+}
+
+// Intercept adds a list of query interceptors to the interceptors stack.
+// A call to `Intercept(f, g, h)` equals to `xunjiservice.Intercept(f(g(h())))`.
+func (c *XunjiServiceClient) Intercept(interceptors ...Interceptor) {
+	c.inters.XunjiService = append(c.inters.XunjiService, interceptors...)
+}
+
+// Create returns a builder for creating a XunjiService entity.
+func (c *XunjiServiceClient) Create() *XunjiServiceCreate {
+	mutation := newXunjiServiceMutation(c.config, OpCreate)
+	return &XunjiServiceCreate{config: c.config, hooks: c.Hooks(), mutation: mutation}
+}
+
+// CreateBulk returns a builder for creating a bulk of XunjiService entities.
+func (c *XunjiServiceClient) CreateBulk(builders ...*XunjiServiceCreate) *XunjiServiceCreateBulk {
+	return &XunjiServiceCreateBulk{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 *XunjiServiceClient) MapCreateBulk(slice any, setFunc func(*XunjiServiceCreate, int)) *XunjiServiceCreateBulk {
+	rv := reflect.ValueOf(slice)
+	if rv.Kind() != reflect.Slice {
+		return &XunjiServiceCreateBulk{err: fmt.Errorf("calling to XunjiServiceClient.MapCreateBulk with wrong type %T, need slice", slice)}
+	}
+	builders := make([]*XunjiServiceCreate, rv.Len())
+	for i := 0; i < rv.Len(); i++ {
+		builders[i] = c.Create()
+		setFunc(builders[i], i)
+	}
+	return &XunjiServiceCreateBulk{config: c.config, builders: builders}
+}
+
+// Update returns an update builder for XunjiService.
+func (c *XunjiServiceClient) Update() *XunjiServiceUpdate {
+	mutation := newXunjiServiceMutation(c.config, OpUpdate)
+	return &XunjiServiceUpdate{config: c.config, hooks: c.Hooks(), mutation: mutation}
+}
+
+// UpdateOne returns an update builder for the given entity.
+func (c *XunjiServiceClient) UpdateOne(xs *XunjiService) *XunjiServiceUpdateOne {
+	mutation := newXunjiServiceMutation(c.config, OpUpdateOne, withXunjiService(xs))
+	return &XunjiServiceUpdateOne{config: c.config, hooks: c.Hooks(), mutation: mutation}
+}
+
+// UpdateOneID returns an update builder for the given id.
+func (c *XunjiServiceClient) UpdateOneID(id uint64) *XunjiServiceUpdateOne {
+	mutation := newXunjiServiceMutation(c.config, OpUpdateOne, withXunjiServiceID(id))
+	return &XunjiServiceUpdateOne{config: c.config, hooks: c.Hooks(), mutation: mutation}
+}
+
+// Delete returns a delete builder for XunjiService.
+func (c *XunjiServiceClient) Delete() *XunjiServiceDelete {
+	mutation := newXunjiServiceMutation(c.config, OpDelete)
+	return &XunjiServiceDelete{config: c.config, hooks: c.Hooks(), mutation: mutation}
+}
+
+// DeleteOne returns a builder for deleting the given entity.
+func (c *XunjiServiceClient) DeleteOne(xs *XunjiService) *XunjiServiceDeleteOne {
+	return c.DeleteOneID(xs.ID)
+}
+
+// DeleteOneID returns a builder for deleting the given entity by its id.
+func (c *XunjiServiceClient) DeleteOneID(id uint64) *XunjiServiceDeleteOne {
+	builder := c.Delete().Where(xunjiservice.ID(id))
+	builder.mutation.id = &id
+	builder.mutation.op = OpDeleteOne
+	return &XunjiServiceDeleteOne{builder}
+}
+
+// Query returns a query builder for XunjiService.
+func (c *XunjiServiceClient) Query() *XunjiServiceQuery {
+	return &XunjiServiceQuery{
+		config: c.config,
+		ctx:    &QueryContext{Type: TypeXunjiService},
+		inters: c.Interceptors(),
+	}
+}
+
+// Get returns a XunjiService entity by its id.
+func (c *XunjiServiceClient) Get(ctx context.Context, id uint64) (*XunjiService, error) {
+	return c.Query().Where(xunjiservice.ID(id)).Only(ctx)
+}
+
+// GetX is like Get, but panics if an error occurs.
+func (c *XunjiServiceClient) GetX(ctx context.Context, id uint64) *XunjiService {
+	obj, err := c.Get(ctx, id)
+	if err != nil {
+		panic(err)
+	}
+	return obj
+}
+
+// QueryAgent queries the agent edge of a XunjiService.
+func (c *XunjiServiceClient) QueryAgent(xs *XunjiService) *AgentQuery {
+	query := (&AgentClient{config: c.config}).Query()
+	query.path = func(context.Context) (fromV *sql.Selector, _ error) {
+		id := xs.ID
+		step := sqlgraph.NewStep(
+			sqlgraph.From(xunjiservice.Table, xunjiservice.FieldID, id),
+			sqlgraph.To(agent.Table, agent.FieldID),
+			sqlgraph.Edge(sqlgraph.M2O, true, xunjiservice.AgentTable, xunjiservice.AgentColumn),
+		)
+		fromV = sqlgraph.Neighbors(xs.driver.Dialect(), step)
+		return fromV, nil
+	}
+	return query
+}
+
+// Hooks returns the client hooks.
+func (c *XunjiServiceClient) Hooks() []Hook {
+	hooks := c.hooks.XunjiService
+	return append(hooks[:len(hooks):len(hooks)], xunjiservice.Hooks[:]...)
+}
+
+// Interceptors returns the client interceptors.
+func (c *XunjiServiceClient) Interceptors() []Interceptor {
+	inters := c.inters.XunjiService
+	return append(inters[:len(inters):len(inters)], xunjiservice.Interceptors[:]...)
+}
+
+func (c *XunjiServiceClient) mutate(ctx context.Context, m *XunjiServiceMutation) (Value, error) {
+	switch m.Op() {
+	case OpCreate:
+		return (&XunjiServiceCreate{config: c.config, hooks: c.Hooks(), mutation: m}).Save(ctx)
+	case OpUpdate:
+		return (&XunjiServiceUpdate{config: c.config, hooks: c.Hooks(), mutation: m}).Save(ctx)
+	case OpUpdateOne:
+		return (&XunjiServiceUpdateOne{config: c.config, hooks: c.Hooks(), mutation: m}).Save(ctx)
+	case OpDelete, OpDeleteOne:
+		return (&XunjiServiceDelete{config: c.config, hooks: c.Hooks(), mutation: m}).Exec(ctx)
+	default:
+		return nil, fmt.Errorf("ent: unknown XunjiService mutation op: %q", m.Op())
+	}
+}
+
 // hooks and interceptors per client, for fast access.
 type (
 	hooks struct {
@@ -7135,7 +7455,7 @@ type (
 		PayRecharge, Server, SopNode, SopStage, SopTask, Token, Tutorial, UsageDetail,
 		UsageStatisticDay, UsageStatisticHour, UsageStatisticMonth, UsageTotal,
 		Whatsapp, WhatsappChannel, WorkExperience, WpChatroom, WpChatroomMember, Wx,
-		WxCard, WxCardUser, WxCardVisit []ent.Hook
+		WxCard, WxCardUser, WxCardVisit, Xunji, XunjiService []ent.Hook
 	}
 	inters struct {
 		Agent, AgentBase, AliyunAvatar, AllocAgent, ApiKey, BatchMsg, Category,
@@ -7145,7 +7465,7 @@ type (
 		PayRecharge, Server, SopNode, SopStage, SopTask, Token, Tutorial, UsageDetail,
 		UsageStatisticDay, UsageStatisticHour, UsageStatisticMonth, UsageTotal,
 		Whatsapp, WhatsappChannel, WorkExperience, WpChatroom, WpChatroomMember, Wx,
-		WxCard, WxCardUser, WxCardVisit []ent.Interceptor
+		WxCard, WxCardUser, WxCardVisit, Xunji, XunjiService []ent.Interceptor
 	}
 )
 

+ 3 - 3
ent/creditbalance.go

@@ -25,8 +25,8 @@ type CreditBalance struct {
 	DeletedAt time.Time `json:"deleted_at,omitempty"`
 	// user_id | 用户ID
 	UserID string `json:"user_id,omitempty"`
-	// role | 角色设定
-	Balance float32 `json:"balance,omitempty"`
+	// balance | 积分余额
+	Balance float64 `json:"balance,omitempty"`
 	// status | 状态 1-正常 2-禁用
 	Status int `json:"status,omitempty"`
 	// organization_id | 租户ID
@@ -96,7 +96,7 @@ func (cb *CreditBalance) assignValues(columns []string, values []any) error {
 			if value, ok := values[i].(*sql.NullFloat64); !ok {
 				return fmt.Errorf("unexpected type %T for field balance", values[i])
 			} else if value.Valid {
-				cb.Balance = float32(value.Float64)
+				cb.Balance = value.Float64
 			}
 		case creditbalance.FieldStatus:
 			if value, ok := values[i].(*sql.NullInt64); !ok {

+ 9 - 9
ent/creditbalance/where.go

@@ -75,7 +75,7 @@ func UserID(v string) predicate.CreditBalance {
 }
 
 // Balance applies equality check predicate on the "balance" field. It's identical to BalanceEQ.
-func Balance(v float32) predicate.CreditBalance {
+func Balance(v float64) predicate.CreditBalance {
 	return predicate.CreditBalance(sql.FieldEQ(FieldBalance, v))
 }
 
@@ -295,42 +295,42 @@ func UserIDContainsFold(v string) predicate.CreditBalance {
 }
 
 // BalanceEQ applies the EQ predicate on the "balance" field.
-func BalanceEQ(v float32) predicate.CreditBalance {
+func BalanceEQ(v float64) predicate.CreditBalance {
 	return predicate.CreditBalance(sql.FieldEQ(FieldBalance, v))
 }
 
 // BalanceNEQ applies the NEQ predicate on the "balance" field.
-func BalanceNEQ(v float32) predicate.CreditBalance {
+func BalanceNEQ(v float64) predicate.CreditBalance {
 	return predicate.CreditBalance(sql.FieldNEQ(FieldBalance, v))
 }
 
 // BalanceIn applies the In predicate on the "balance" field.
-func BalanceIn(vs ...float32) predicate.CreditBalance {
+func BalanceIn(vs ...float64) predicate.CreditBalance {
 	return predicate.CreditBalance(sql.FieldIn(FieldBalance, vs...))
 }
 
 // BalanceNotIn applies the NotIn predicate on the "balance" field.
-func BalanceNotIn(vs ...float32) predicate.CreditBalance {
+func BalanceNotIn(vs ...float64) predicate.CreditBalance {
 	return predicate.CreditBalance(sql.FieldNotIn(FieldBalance, vs...))
 }
 
 // BalanceGT applies the GT predicate on the "balance" field.
-func BalanceGT(v float32) predicate.CreditBalance {
+func BalanceGT(v float64) predicate.CreditBalance {
 	return predicate.CreditBalance(sql.FieldGT(FieldBalance, v))
 }
 
 // BalanceGTE applies the GTE predicate on the "balance" field.
-func BalanceGTE(v float32) predicate.CreditBalance {
+func BalanceGTE(v float64) predicate.CreditBalance {
 	return predicate.CreditBalance(sql.FieldGTE(FieldBalance, v))
 }
 
 // BalanceLT applies the LT predicate on the "balance" field.
-func BalanceLT(v float32) predicate.CreditBalance {
+func BalanceLT(v float64) predicate.CreditBalance {
 	return predicate.CreditBalance(sql.FieldLT(FieldBalance, v))
 }
 
 // BalanceLTE applies the LTE predicate on the "balance" field.
-func BalanceLTE(v float32) predicate.CreditBalance {
+func BalanceLTE(v float64) predicate.CreditBalance {
 	return predicate.CreditBalance(sql.FieldLTE(FieldBalance, v))
 }
 

+ 8 - 8
ent/creditbalance_create.go

@@ -79,7 +79,7 @@ func (cbc *CreditBalanceCreate) SetNillableUserID(s *string) *CreditBalanceCreat
 }
 
 // SetBalance sets the "balance" field.
-func (cbc *CreditBalanceCreate) SetBalance(f float32) *CreditBalanceCreate {
+func (cbc *CreditBalanceCreate) SetBalance(f float64) *CreditBalanceCreate {
 	cbc.mutation.SetBalance(f)
 	return cbc
 }
@@ -242,7 +242,7 @@ func (cbc *CreditBalanceCreate) createSpec() (*CreditBalance, *sqlgraph.CreateSp
 		_node.UserID = value
 	}
 	if value, ok := cbc.mutation.Balance(); ok {
-		_spec.SetField(creditbalance.FieldBalance, field.TypeFloat32, value)
+		_spec.SetField(creditbalance.FieldBalance, field.TypeFloat64, value)
 		_node.Balance = value
 	}
 	if value, ok := cbc.mutation.Status(); ok {
@@ -354,7 +354,7 @@ func (u *CreditBalanceUpsert) ClearUserID() *CreditBalanceUpsert {
 }
 
 // SetBalance sets the "balance" field.
-func (u *CreditBalanceUpsert) SetBalance(v float32) *CreditBalanceUpsert {
+func (u *CreditBalanceUpsert) SetBalance(v float64) *CreditBalanceUpsert {
 	u.Set(creditbalance.FieldBalance, v)
 	return u
 }
@@ -366,7 +366,7 @@ func (u *CreditBalanceUpsert) UpdateBalance() *CreditBalanceUpsert {
 }
 
 // AddBalance adds v to the "balance" field.
-func (u *CreditBalanceUpsert) AddBalance(v float32) *CreditBalanceUpsert {
+func (u *CreditBalanceUpsert) AddBalance(v float64) *CreditBalanceUpsert {
 	u.Add(creditbalance.FieldBalance, v)
 	return u
 }
@@ -527,14 +527,14 @@ func (u *CreditBalanceUpsertOne) ClearUserID() *CreditBalanceUpsertOne {
 }
 
 // SetBalance sets the "balance" field.
-func (u *CreditBalanceUpsertOne) SetBalance(v float32) *CreditBalanceUpsertOne {
+func (u *CreditBalanceUpsertOne) SetBalance(v float64) *CreditBalanceUpsertOne {
 	return u.Update(func(s *CreditBalanceUpsert) {
 		s.SetBalance(v)
 	})
 }
 
 // AddBalance adds v to the "balance" field.
-func (u *CreditBalanceUpsertOne) AddBalance(v float32) *CreditBalanceUpsertOne {
+func (u *CreditBalanceUpsertOne) AddBalance(v float64) *CreditBalanceUpsertOne {
 	return u.Update(func(s *CreditBalanceUpsert) {
 		s.AddBalance(v)
 	})
@@ -877,14 +877,14 @@ func (u *CreditBalanceUpsertBulk) ClearUserID() *CreditBalanceUpsertBulk {
 }
 
 // SetBalance sets the "balance" field.
-func (u *CreditBalanceUpsertBulk) SetBalance(v float32) *CreditBalanceUpsertBulk {
+func (u *CreditBalanceUpsertBulk) SetBalance(v float64) *CreditBalanceUpsertBulk {
 	return u.Update(func(s *CreditBalanceUpsert) {
 		s.SetBalance(v)
 	})
 }
 
 // AddBalance adds v to the "balance" field.
-func (u *CreditBalanceUpsertBulk) AddBalance(v float32) *CreditBalanceUpsertBulk {
+func (u *CreditBalanceUpsertBulk) AddBalance(v float64) *CreditBalanceUpsertBulk {
 	return u.Update(func(s *CreditBalanceUpsert) {
 		s.AddBalance(v)
 	})

+ 10 - 10
ent/creditbalance_update.go

@@ -75,14 +75,14 @@ func (cbu *CreditBalanceUpdate) ClearUserID() *CreditBalanceUpdate {
 }
 
 // SetBalance sets the "balance" field.
-func (cbu *CreditBalanceUpdate) SetBalance(f float32) *CreditBalanceUpdate {
+func (cbu *CreditBalanceUpdate) SetBalance(f float64) *CreditBalanceUpdate {
 	cbu.mutation.ResetBalance()
 	cbu.mutation.SetBalance(f)
 	return cbu
 }
 
 // SetNillableBalance sets the "balance" field if the given value is not nil.
-func (cbu *CreditBalanceUpdate) SetNillableBalance(f *float32) *CreditBalanceUpdate {
+func (cbu *CreditBalanceUpdate) SetNillableBalance(f *float64) *CreditBalanceUpdate {
 	if f != nil {
 		cbu.SetBalance(*f)
 	}
@@ -90,7 +90,7 @@ func (cbu *CreditBalanceUpdate) SetNillableBalance(f *float32) *CreditBalanceUpd
 }
 
 // AddBalance adds f to the "balance" field.
-func (cbu *CreditBalanceUpdate) AddBalance(f float32) *CreditBalanceUpdate {
+func (cbu *CreditBalanceUpdate) AddBalance(f float64) *CreditBalanceUpdate {
 	cbu.mutation.AddBalance(f)
 	return cbu
 }
@@ -234,10 +234,10 @@ func (cbu *CreditBalanceUpdate) sqlSave(ctx context.Context) (n int, err error)
 		_spec.ClearField(creditbalance.FieldUserID, field.TypeString)
 	}
 	if value, ok := cbu.mutation.Balance(); ok {
-		_spec.SetField(creditbalance.FieldBalance, field.TypeFloat32, value)
+		_spec.SetField(creditbalance.FieldBalance, field.TypeFloat64, value)
 	}
 	if value, ok := cbu.mutation.AddedBalance(); ok {
-		_spec.AddField(creditbalance.FieldBalance, field.TypeFloat32, value)
+		_spec.AddField(creditbalance.FieldBalance, field.TypeFloat64, value)
 	}
 	if value, ok := cbu.mutation.Status(); ok {
 		_spec.SetField(creditbalance.FieldStatus, field.TypeInt, value)
@@ -324,14 +324,14 @@ func (cbuo *CreditBalanceUpdateOne) ClearUserID() *CreditBalanceUpdateOne {
 }
 
 // SetBalance sets the "balance" field.
-func (cbuo *CreditBalanceUpdateOne) SetBalance(f float32) *CreditBalanceUpdateOne {
+func (cbuo *CreditBalanceUpdateOne) SetBalance(f float64) *CreditBalanceUpdateOne {
 	cbuo.mutation.ResetBalance()
 	cbuo.mutation.SetBalance(f)
 	return cbuo
 }
 
 // SetNillableBalance sets the "balance" field if the given value is not nil.
-func (cbuo *CreditBalanceUpdateOne) SetNillableBalance(f *float32) *CreditBalanceUpdateOne {
+func (cbuo *CreditBalanceUpdateOne) SetNillableBalance(f *float64) *CreditBalanceUpdateOne {
 	if f != nil {
 		cbuo.SetBalance(*f)
 	}
@@ -339,7 +339,7 @@ func (cbuo *CreditBalanceUpdateOne) SetNillableBalance(f *float32) *CreditBalanc
 }
 
 // AddBalance adds f to the "balance" field.
-func (cbuo *CreditBalanceUpdateOne) AddBalance(f float32) *CreditBalanceUpdateOne {
+func (cbuo *CreditBalanceUpdateOne) AddBalance(f float64) *CreditBalanceUpdateOne {
 	cbuo.mutation.AddBalance(f)
 	return cbuo
 }
@@ -513,10 +513,10 @@ func (cbuo *CreditBalanceUpdateOne) sqlSave(ctx context.Context) (_node *CreditB
 		_spec.ClearField(creditbalance.FieldUserID, field.TypeString)
 	}
 	if value, ok := cbuo.mutation.Balance(); ok {
-		_spec.SetField(creditbalance.FieldBalance, field.TypeFloat32, value)
+		_spec.SetField(creditbalance.FieldBalance, field.TypeFloat64, value)
 	}
 	if value, ok := cbuo.mutation.AddedBalance(); ok {
-		_spec.AddField(creditbalance.FieldBalance, field.TypeFloat32, value)
+		_spec.AddField(creditbalance.FieldBalance, field.TypeFloat64, value)
 	}
 	if value, ok := cbuo.mutation.Status(); ok {
 		_spec.SetField(creditbalance.FieldStatus, field.TypeInt, value)

+ 48 - 4
ent/creditusage.go

@@ -26,7 +26,15 @@ type CreditUsage struct {
 	// user_id | 用户ID
 	UserID string `json:"user_id,omitempty"`
 	// number | 积分改变量
-	Number float32 `json:"number,omitempty"`
+	Number float64 `json:"number,omitempty"`
+	// pay_number | 充值金额
+	PayNumber float64 `json:"pay_number,omitempty"`
+	// before_number | 变动前金额
+	BeforeNumber float64 `json:"before_number,omitempty"`
+	// after_number | 变动后金额
+	AfterNumber float64 `json:"after_number,omitempty"`
+	// pay_method | 充值方式
+	PayMethod int `json:"pay_method,omitempty"`
 	// status | 状态 1-正常 2-禁用
 	Status int `json:"status,omitempty"`
 	// ntype | 积分变化类型:1-消耗 2-增加
@@ -49,9 +57,9 @@ func (*CreditUsage) scanValues(columns []string) ([]any, error) {
 	values := make([]any, len(columns))
 	for i := range columns {
 		switch columns[i] {
-		case creditusage.FieldNumber:
+		case creditusage.FieldNumber, creditusage.FieldPayNumber, creditusage.FieldBeforeNumber, creditusage.FieldAfterNumber:
 			values[i] = new(sql.NullFloat64)
-		case creditusage.FieldID, creditusage.FieldStatus, creditusage.FieldNtype, creditusage.FieldOrganizationID, creditusage.FieldNid:
+		case creditusage.FieldID, creditusage.FieldPayMethod, creditusage.FieldStatus, creditusage.FieldNtype, creditusage.FieldOrganizationID, creditusage.FieldNid:
 			values[i] = new(sql.NullInt64)
 		case creditusage.FieldUserID, creditusage.FieldTable, creditusage.FieldReason, creditusage.FieldOperator:
 			values[i] = new(sql.NullString)
@@ -106,7 +114,31 @@ func (cu *CreditUsage) assignValues(columns []string, values []any) error {
 			if value, ok := values[i].(*sql.NullFloat64); !ok {
 				return fmt.Errorf("unexpected type %T for field number", values[i])
 			} else if value.Valid {
-				cu.Number = float32(value.Float64)
+				cu.Number = value.Float64
+			}
+		case creditusage.FieldPayNumber:
+			if value, ok := values[i].(*sql.NullFloat64); !ok {
+				return fmt.Errorf("unexpected type %T for field pay_number", values[i])
+			} else if value.Valid {
+				cu.PayNumber = value.Float64
+			}
+		case creditusage.FieldBeforeNumber:
+			if value, ok := values[i].(*sql.NullFloat64); !ok {
+				return fmt.Errorf("unexpected type %T for field before_number", values[i])
+			} else if value.Valid {
+				cu.BeforeNumber = value.Float64
+			}
+		case creditusage.FieldAfterNumber:
+			if value, ok := values[i].(*sql.NullFloat64); !ok {
+				return fmt.Errorf("unexpected type %T for field after_number", values[i])
+			} else if value.Valid {
+				cu.AfterNumber = value.Float64
+			}
+		case creditusage.FieldPayMethod:
+			if value, ok := values[i].(*sql.NullInt64); !ok {
+				return fmt.Errorf("unexpected type %T for field pay_method", values[i])
+			} else if value.Valid {
+				cu.PayMethod = int(value.Int64)
 			}
 		case creditusage.FieldStatus:
 			if value, ok := values[i].(*sql.NullInt64); !ok {
@@ -201,6 +233,18 @@ func (cu *CreditUsage) String() string {
 	builder.WriteString("number=")
 	builder.WriteString(fmt.Sprintf("%v", cu.Number))
 	builder.WriteString(", ")
+	builder.WriteString("pay_number=")
+	builder.WriteString(fmt.Sprintf("%v", cu.PayNumber))
+	builder.WriteString(", ")
+	builder.WriteString("before_number=")
+	builder.WriteString(fmt.Sprintf("%v", cu.BeforeNumber))
+	builder.WriteString(", ")
+	builder.WriteString("after_number=")
+	builder.WriteString(fmt.Sprintf("%v", cu.AfterNumber))
+	builder.WriteString(", ")
+	builder.WriteString("pay_method=")
+	builder.WriteString(fmt.Sprintf("%v", cu.PayMethod))
+	builder.WriteString(", ")
 	builder.WriteString("status=")
 	builder.WriteString(fmt.Sprintf("%v", cu.Status))
 	builder.WriteString(", ")

+ 34 - 0
ent/creditusage/creditusage.go

@@ -24,6 +24,14 @@ const (
 	FieldUserID = "user_id"
 	// FieldNumber holds the string denoting the number field in the database.
 	FieldNumber = "number"
+	// FieldPayNumber holds the string denoting the pay_number field in the database.
+	FieldPayNumber = "pay_number"
+	// FieldBeforeNumber holds the string denoting the before_number field in the database.
+	FieldBeforeNumber = "before_number"
+	// FieldAfterNumber holds the string denoting the after_number field in the database.
+	FieldAfterNumber = "after_number"
+	// FieldPayMethod holds the string denoting the pay_method field in the database.
+	FieldPayMethod = "pay_method"
 	// FieldStatus holds the string denoting the status field in the database.
 	FieldStatus = "status"
 	// FieldNtype holds the string denoting the ntype field in the database.
@@ -50,6 +58,10 @@ var Columns = []string{
 	FieldDeletedAt,
 	FieldUserID,
 	FieldNumber,
+	FieldPayNumber,
+	FieldBeforeNumber,
+	FieldAfterNumber,
+	FieldPayMethod,
 	FieldStatus,
 	FieldNtype,
 	FieldTable,
@@ -85,6 +97,8 @@ var (
 	UpdateDefaultUpdatedAt func() time.Time
 	// UserIDValidator is a validator for the "user_id" field. It is called by the builders before save.
 	UserIDValidator func(string) error
+	// DefaultPayMethod holds the default value on creation for the "pay_method" field.
+	DefaultPayMethod int
 	// DefaultStatus holds the default value on creation for the "status" field.
 	DefaultStatus int
 	// StatusValidator is a validator for the "status" field. It is called by the builders before save.
@@ -138,6 +152,26 @@ func ByNumber(opts ...sql.OrderTermOption) OrderOption {
 	return sql.OrderByField(FieldNumber, opts...).ToFunc()
 }
 
+// ByPayNumber orders the results by the pay_number field.
+func ByPayNumber(opts ...sql.OrderTermOption) OrderOption {
+	return sql.OrderByField(FieldPayNumber, opts...).ToFunc()
+}
+
+// ByBeforeNumber orders the results by the before_number field.
+func ByBeforeNumber(opts ...sql.OrderTermOption) OrderOption {
+	return sql.OrderByField(FieldBeforeNumber, opts...).ToFunc()
+}
+
+// ByAfterNumber orders the results by the after_number field.
+func ByAfterNumber(opts ...sql.OrderTermOption) OrderOption {
+	return sql.OrderByField(FieldAfterNumber, opts...).ToFunc()
+}
+
+// ByPayMethod orders the results by the pay_method field.
+func ByPayMethod(opts ...sql.OrderTermOption) OrderOption {
+	return sql.OrderByField(FieldPayMethod, opts...).ToFunc()
+}
+
 // ByStatus orders the results by the status field.
 func ByStatus(opts ...sql.OrderTermOption) OrderOption {
 	return sql.OrderByField(FieldStatus, opts...).ToFunc()

+ 229 - 9
ent/creditusage/where.go

@@ -75,10 +75,30 @@ func UserID(v string) predicate.CreditUsage {
 }
 
 // Number applies equality check predicate on the "number" field. It's identical to NumberEQ.
-func Number(v float32) predicate.CreditUsage {
+func Number(v float64) predicate.CreditUsage {
 	return predicate.CreditUsage(sql.FieldEQ(FieldNumber, v))
 }
 
+// PayNumber applies equality check predicate on the "pay_number" field. It's identical to PayNumberEQ.
+func PayNumber(v float64) predicate.CreditUsage {
+	return predicate.CreditUsage(sql.FieldEQ(FieldPayNumber, v))
+}
+
+// BeforeNumber applies equality check predicate on the "before_number" field. It's identical to BeforeNumberEQ.
+func BeforeNumber(v float64) predicate.CreditUsage {
+	return predicate.CreditUsage(sql.FieldEQ(FieldBeforeNumber, v))
+}
+
+// AfterNumber applies equality check predicate on the "after_number" field. It's identical to AfterNumberEQ.
+func AfterNumber(v float64) predicate.CreditUsage {
+	return predicate.CreditUsage(sql.FieldEQ(FieldAfterNumber, v))
+}
+
+// PayMethod applies equality check predicate on the "pay_method" field. It's identical to PayMethodEQ.
+func PayMethod(v int) predicate.CreditUsage {
+	return predicate.CreditUsage(sql.FieldEQ(FieldPayMethod, v))
+}
+
 // Status applies equality check predicate on the "status" field. It's identical to StatusEQ.
 func Status(v int) predicate.CreditUsage {
 	return predicate.CreditUsage(sql.FieldEQ(FieldStatus, v))
@@ -315,45 +335,245 @@ func UserIDContainsFold(v string) predicate.CreditUsage {
 }
 
 // NumberEQ applies the EQ predicate on the "number" field.
-func NumberEQ(v float32) predicate.CreditUsage {
+func NumberEQ(v float64) predicate.CreditUsage {
 	return predicate.CreditUsage(sql.FieldEQ(FieldNumber, v))
 }
 
 // NumberNEQ applies the NEQ predicate on the "number" field.
-func NumberNEQ(v float32) predicate.CreditUsage {
+func NumberNEQ(v float64) predicate.CreditUsage {
 	return predicate.CreditUsage(sql.FieldNEQ(FieldNumber, v))
 }
 
 // NumberIn applies the In predicate on the "number" field.
-func NumberIn(vs ...float32) predicate.CreditUsage {
+func NumberIn(vs ...float64) predicate.CreditUsage {
 	return predicate.CreditUsage(sql.FieldIn(FieldNumber, vs...))
 }
 
 // NumberNotIn applies the NotIn predicate on the "number" field.
-func NumberNotIn(vs ...float32) predicate.CreditUsage {
+func NumberNotIn(vs ...float64) predicate.CreditUsage {
 	return predicate.CreditUsage(sql.FieldNotIn(FieldNumber, vs...))
 }
 
 // NumberGT applies the GT predicate on the "number" field.
-func NumberGT(v float32) predicate.CreditUsage {
+func NumberGT(v float64) predicate.CreditUsage {
 	return predicate.CreditUsage(sql.FieldGT(FieldNumber, v))
 }
 
 // NumberGTE applies the GTE predicate on the "number" field.
-func NumberGTE(v float32) predicate.CreditUsage {
+func NumberGTE(v float64) predicate.CreditUsage {
 	return predicate.CreditUsage(sql.FieldGTE(FieldNumber, v))
 }
 
 // NumberLT applies the LT predicate on the "number" field.
-func NumberLT(v float32) predicate.CreditUsage {
+func NumberLT(v float64) predicate.CreditUsage {
 	return predicate.CreditUsage(sql.FieldLT(FieldNumber, v))
 }
 
 // NumberLTE applies the LTE predicate on the "number" field.
-func NumberLTE(v float32) predicate.CreditUsage {
+func NumberLTE(v float64) predicate.CreditUsage {
 	return predicate.CreditUsage(sql.FieldLTE(FieldNumber, v))
 }
 
+// PayNumberEQ applies the EQ predicate on the "pay_number" field.
+func PayNumberEQ(v float64) predicate.CreditUsage {
+	return predicate.CreditUsage(sql.FieldEQ(FieldPayNumber, v))
+}
+
+// PayNumberNEQ applies the NEQ predicate on the "pay_number" field.
+func PayNumberNEQ(v float64) predicate.CreditUsage {
+	return predicate.CreditUsage(sql.FieldNEQ(FieldPayNumber, v))
+}
+
+// PayNumberIn applies the In predicate on the "pay_number" field.
+func PayNumberIn(vs ...float64) predicate.CreditUsage {
+	return predicate.CreditUsage(sql.FieldIn(FieldPayNumber, vs...))
+}
+
+// PayNumberNotIn applies the NotIn predicate on the "pay_number" field.
+func PayNumberNotIn(vs ...float64) predicate.CreditUsage {
+	return predicate.CreditUsage(sql.FieldNotIn(FieldPayNumber, vs...))
+}
+
+// PayNumberGT applies the GT predicate on the "pay_number" field.
+func PayNumberGT(v float64) predicate.CreditUsage {
+	return predicate.CreditUsage(sql.FieldGT(FieldPayNumber, v))
+}
+
+// PayNumberGTE applies the GTE predicate on the "pay_number" field.
+func PayNumberGTE(v float64) predicate.CreditUsage {
+	return predicate.CreditUsage(sql.FieldGTE(FieldPayNumber, v))
+}
+
+// PayNumberLT applies the LT predicate on the "pay_number" field.
+func PayNumberLT(v float64) predicate.CreditUsage {
+	return predicate.CreditUsage(sql.FieldLT(FieldPayNumber, v))
+}
+
+// PayNumberLTE applies the LTE predicate on the "pay_number" field.
+func PayNumberLTE(v float64) predicate.CreditUsage {
+	return predicate.CreditUsage(sql.FieldLTE(FieldPayNumber, v))
+}
+
+// PayNumberIsNil applies the IsNil predicate on the "pay_number" field.
+func PayNumberIsNil() predicate.CreditUsage {
+	return predicate.CreditUsage(sql.FieldIsNull(FieldPayNumber))
+}
+
+// PayNumberNotNil applies the NotNil predicate on the "pay_number" field.
+func PayNumberNotNil() predicate.CreditUsage {
+	return predicate.CreditUsage(sql.FieldNotNull(FieldPayNumber))
+}
+
+// BeforeNumberEQ applies the EQ predicate on the "before_number" field.
+func BeforeNumberEQ(v float64) predicate.CreditUsage {
+	return predicate.CreditUsage(sql.FieldEQ(FieldBeforeNumber, v))
+}
+
+// BeforeNumberNEQ applies the NEQ predicate on the "before_number" field.
+func BeforeNumberNEQ(v float64) predicate.CreditUsage {
+	return predicate.CreditUsage(sql.FieldNEQ(FieldBeforeNumber, v))
+}
+
+// BeforeNumberIn applies the In predicate on the "before_number" field.
+func BeforeNumberIn(vs ...float64) predicate.CreditUsage {
+	return predicate.CreditUsage(sql.FieldIn(FieldBeforeNumber, vs...))
+}
+
+// BeforeNumberNotIn applies the NotIn predicate on the "before_number" field.
+func BeforeNumberNotIn(vs ...float64) predicate.CreditUsage {
+	return predicate.CreditUsage(sql.FieldNotIn(FieldBeforeNumber, vs...))
+}
+
+// BeforeNumberGT applies the GT predicate on the "before_number" field.
+func BeforeNumberGT(v float64) predicate.CreditUsage {
+	return predicate.CreditUsage(sql.FieldGT(FieldBeforeNumber, v))
+}
+
+// BeforeNumberGTE applies the GTE predicate on the "before_number" field.
+func BeforeNumberGTE(v float64) predicate.CreditUsage {
+	return predicate.CreditUsage(sql.FieldGTE(FieldBeforeNumber, v))
+}
+
+// BeforeNumberLT applies the LT predicate on the "before_number" field.
+func BeforeNumberLT(v float64) predicate.CreditUsage {
+	return predicate.CreditUsage(sql.FieldLT(FieldBeforeNumber, v))
+}
+
+// BeforeNumberLTE applies the LTE predicate on the "before_number" field.
+func BeforeNumberLTE(v float64) predicate.CreditUsage {
+	return predicate.CreditUsage(sql.FieldLTE(FieldBeforeNumber, v))
+}
+
+// BeforeNumberIsNil applies the IsNil predicate on the "before_number" field.
+func BeforeNumberIsNil() predicate.CreditUsage {
+	return predicate.CreditUsage(sql.FieldIsNull(FieldBeforeNumber))
+}
+
+// BeforeNumberNotNil applies the NotNil predicate on the "before_number" field.
+func BeforeNumberNotNil() predicate.CreditUsage {
+	return predicate.CreditUsage(sql.FieldNotNull(FieldBeforeNumber))
+}
+
+// AfterNumberEQ applies the EQ predicate on the "after_number" field.
+func AfterNumberEQ(v float64) predicate.CreditUsage {
+	return predicate.CreditUsage(sql.FieldEQ(FieldAfterNumber, v))
+}
+
+// AfterNumberNEQ applies the NEQ predicate on the "after_number" field.
+func AfterNumberNEQ(v float64) predicate.CreditUsage {
+	return predicate.CreditUsage(sql.FieldNEQ(FieldAfterNumber, v))
+}
+
+// AfterNumberIn applies the In predicate on the "after_number" field.
+func AfterNumberIn(vs ...float64) predicate.CreditUsage {
+	return predicate.CreditUsage(sql.FieldIn(FieldAfterNumber, vs...))
+}
+
+// AfterNumberNotIn applies the NotIn predicate on the "after_number" field.
+func AfterNumberNotIn(vs ...float64) predicate.CreditUsage {
+	return predicate.CreditUsage(sql.FieldNotIn(FieldAfterNumber, vs...))
+}
+
+// AfterNumberGT applies the GT predicate on the "after_number" field.
+func AfterNumberGT(v float64) predicate.CreditUsage {
+	return predicate.CreditUsage(sql.FieldGT(FieldAfterNumber, v))
+}
+
+// AfterNumberGTE applies the GTE predicate on the "after_number" field.
+func AfterNumberGTE(v float64) predicate.CreditUsage {
+	return predicate.CreditUsage(sql.FieldGTE(FieldAfterNumber, v))
+}
+
+// AfterNumberLT applies the LT predicate on the "after_number" field.
+func AfterNumberLT(v float64) predicate.CreditUsage {
+	return predicate.CreditUsage(sql.FieldLT(FieldAfterNumber, v))
+}
+
+// AfterNumberLTE applies the LTE predicate on the "after_number" field.
+func AfterNumberLTE(v float64) predicate.CreditUsage {
+	return predicate.CreditUsage(sql.FieldLTE(FieldAfterNumber, v))
+}
+
+// AfterNumberIsNil applies the IsNil predicate on the "after_number" field.
+func AfterNumberIsNil() predicate.CreditUsage {
+	return predicate.CreditUsage(sql.FieldIsNull(FieldAfterNumber))
+}
+
+// AfterNumberNotNil applies the NotNil predicate on the "after_number" field.
+func AfterNumberNotNil() predicate.CreditUsage {
+	return predicate.CreditUsage(sql.FieldNotNull(FieldAfterNumber))
+}
+
+// PayMethodEQ applies the EQ predicate on the "pay_method" field.
+func PayMethodEQ(v int) predicate.CreditUsage {
+	return predicate.CreditUsage(sql.FieldEQ(FieldPayMethod, v))
+}
+
+// PayMethodNEQ applies the NEQ predicate on the "pay_method" field.
+func PayMethodNEQ(v int) predicate.CreditUsage {
+	return predicate.CreditUsage(sql.FieldNEQ(FieldPayMethod, v))
+}
+
+// PayMethodIn applies the In predicate on the "pay_method" field.
+func PayMethodIn(vs ...int) predicate.CreditUsage {
+	return predicate.CreditUsage(sql.FieldIn(FieldPayMethod, vs...))
+}
+
+// PayMethodNotIn applies the NotIn predicate on the "pay_method" field.
+func PayMethodNotIn(vs ...int) predicate.CreditUsage {
+	return predicate.CreditUsage(sql.FieldNotIn(FieldPayMethod, vs...))
+}
+
+// PayMethodGT applies the GT predicate on the "pay_method" field.
+func PayMethodGT(v int) predicate.CreditUsage {
+	return predicate.CreditUsage(sql.FieldGT(FieldPayMethod, v))
+}
+
+// PayMethodGTE applies the GTE predicate on the "pay_method" field.
+func PayMethodGTE(v int) predicate.CreditUsage {
+	return predicate.CreditUsage(sql.FieldGTE(FieldPayMethod, v))
+}
+
+// PayMethodLT applies the LT predicate on the "pay_method" field.
+func PayMethodLT(v int) predicate.CreditUsage {
+	return predicate.CreditUsage(sql.FieldLT(FieldPayMethod, v))
+}
+
+// PayMethodLTE applies the LTE predicate on the "pay_method" field.
+func PayMethodLTE(v int) predicate.CreditUsage {
+	return predicate.CreditUsage(sql.FieldLTE(FieldPayMethod, v))
+}
+
+// PayMethodIsNil applies the IsNil predicate on the "pay_method" field.
+func PayMethodIsNil() predicate.CreditUsage {
+	return predicate.CreditUsage(sql.FieldIsNull(FieldPayMethod))
+}
+
+// PayMethodNotNil applies the NotNil predicate on the "pay_method" field.
+func PayMethodNotNil() predicate.CreditUsage {
+	return predicate.CreditUsage(sql.FieldNotNull(FieldPayMethod))
+}
+
 // StatusEQ applies the EQ predicate on the "status" field.
 func StatusEQ(v int) predicate.CreditUsage {
 	return predicate.CreditUsage(sql.FieldEQ(FieldStatus, v))

+ 404 - 8
ent/creditusage_create.go

@@ -79,11 +79,67 @@ func (cuc *CreditUsageCreate) SetNillableUserID(s *string) *CreditUsageCreate {
 }
 
 // SetNumber sets the "number" field.
-func (cuc *CreditUsageCreate) SetNumber(f float32) *CreditUsageCreate {
+func (cuc *CreditUsageCreate) SetNumber(f float64) *CreditUsageCreate {
 	cuc.mutation.SetNumber(f)
 	return cuc
 }
 
+// SetPayNumber sets the "pay_number" field.
+func (cuc *CreditUsageCreate) SetPayNumber(f float64) *CreditUsageCreate {
+	cuc.mutation.SetPayNumber(f)
+	return cuc
+}
+
+// SetNillablePayNumber sets the "pay_number" field if the given value is not nil.
+func (cuc *CreditUsageCreate) SetNillablePayNumber(f *float64) *CreditUsageCreate {
+	if f != nil {
+		cuc.SetPayNumber(*f)
+	}
+	return cuc
+}
+
+// SetBeforeNumber sets the "before_number" field.
+func (cuc *CreditUsageCreate) SetBeforeNumber(f float64) *CreditUsageCreate {
+	cuc.mutation.SetBeforeNumber(f)
+	return cuc
+}
+
+// SetNillableBeforeNumber sets the "before_number" field if the given value is not nil.
+func (cuc *CreditUsageCreate) SetNillableBeforeNumber(f *float64) *CreditUsageCreate {
+	if f != nil {
+		cuc.SetBeforeNumber(*f)
+	}
+	return cuc
+}
+
+// SetAfterNumber sets the "after_number" field.
+func (cuc *CreditUsageCreate) SetAfterNumber(f float64) *CreditUsageCreate {
+	cuc.mutation.SetAfterNumber(f)
+	return cuc
+}
+
+// SetNillableAfterNumber sets the "after_number" field if the given value is not nil.
+func (cuc *CreditUsageCreate) SetNillableAfterNumber(f *float64) *CreditUsageCreate {
+	if f != nil {
+		cuc.SetAfterNumber(*f)
+	}
+	return cuc
+}
+
+// SetPayMethod sets the "pay_method" field.
+func (cuc *CreditUsageCreate) SetPayMethod(i int) *CreditUsageCreate {
+	cuc.mutation.SetPayMethod(i)
+	return cuc
+}
+
+// SetNillablePayMethod sets the "pay_method" field if the given value is not nil.
+func (cuc *CreditUsageCreate) SetNillablePayMethod(i *int) *CreditUsageCreate {
+	if i != nil {
+		cuc.SetPayMethod(*i)
+	}
+	return cuc
+}
+
 // SetStatus sets the "status" field.
 func (cuc *CreditUsageCreate) SetStatus(i int) *CreditUsageCreate {
 	cuc.mutation.SetStatus(i)
@@ -239,6 +295,10 @@ func (cuc *CreditUsageCreate) defaults() error {
 		v := creditusage.DefaultUpdatedAt()
 		cuc.mutation.SetUpdatedAt(v)
 	}
+	if _, ok := cuc.mutation.PayMethod(); !ok {
+		v := creditusage.DefaultPayMethod
+		cuc.mutation.SetPayMethod(v)
+	}
 	if _, ok := cuc.mutation.Status(); !ok {
 		v := creditusage.DefaultStatus
 		cuc.mutation.SetStatus(v)
@@ -362,9 +422,25 @@ func (cuc *CreditUsageCreate) createSpec() (*CreditUsage, *sqlgraph.CreateSpec)
 		_node.UserID = value
 	}
 	if value, ok := cuc.mutation.Number(); ok {
-		_spec.SetField(creditusage.FieldNumber, field.TypeFloat32, value)
+		_spec.SetField(creditusage.FieldNumber, field.TypeFloat64, value)
 		_node.Number = value
 	}
+	if value, ok := cuc.mutation.PayNumber(); ok {
+		_spec.SetField(creditusage.FieldPayNumber, field.TypeFloat64, value)
+		_node.PayNumber = value
+	}
+	if value, ok := cuc.mutation.BeforeNumber(); ok {
+		_spec.SetField(creditusage.FieldBeforeNumber, field.TypeFloat64, value)
+		_node.BeforeNumber = value
+	}
+	if value, ok := cuc.mutation.AfterNumber(); ok {
+		_spec.SetField(creditusage.FieldAfterNumber, field.TypeFloat64, value)
+		_node.AfterNumber = value
+	}
+	if value, ok := cuc.mutation.PayMethod(); ok {
+		_spec.SetField(creditusage.FieldPayMethod, field.TypeInt, value)
+		_node.PayMethod = value
+	}
 	if value, ok := cuc.mutation.Status(); ok {
 		_spec.SetField(creditusage.FieldStatus, field.TypeInt, value)
 		_node.Status = value
@@ -494,7 +570,7 @@ func (u *CreditUsageUpsert) ClearUserID() *CreditUsageUpsert {
 }
 
 // SetNumber sets the "number" field.
-func (u *CreditUsageUpsert) SetNumber(v float32) *CreditUsageUpsert {
+func (u *CreditUsageUpsert) SetNumber(v float64) *CreditUsageUpsert {
 	u.Set(creditusage.FieldNumber, v)
 	return u
 }
@@ -506,11 +582,107 @@ func (u *CreditUsageUpsert) UpdateNumber() *CreditUsageUpsert {
 }
 
 // AddNumber adds v to the "number" field.
-func (u *CreditUsageUpsert) AddNumber(v float32) *CreditUsageUpsert {
+func (u *CreditUsageUpsert) AddNumber(v float64) *CreditUsageUpsert {
 	u.Add(creditusage.FieldNumber, v)
 	return u
 }
 
+// SetPayNumber sets the "pay_number" field.
+func (u *CreditUsageUpsert) SetPayNumber(v float64) *CreditUsageUpsert {
+	u.Set(creditusage.FieldPayNumber, v)
+	return u
+}
+
+// UpdatePayNumber sets the "pay_number" field to the value that was provided on create.
+func (u *CreditUsageUpsert) UpdatePayNumber() *CreditUsageUpsert {
+	u.SetExcluded(creditusage.FieldPayNumber)
+	return u
+}
+
+// AddPayNumber adds v to the "pay_number" field.
+func (u *CreditUsageUpsert) AddPayNumber(v float64) *CreditUsageUpsert {
+	u.Add(creditusage.FieldPayNumber, v)
+	return u
+}
+
+// ClearPayNumber clears the value of the "pay_number" field.
+func (u *CreditUsageUpsert) ClearPayNumber() *CreditUsageUpsert {
+	u.SetNull(creditusage.FieldPayNumber)
+	return u
+}
+
+// SetBeforeNumber sets the "before_number" field.
+func (u *CreditUsageUpsert) SetBeforeNumber(v float64) *CreditUsageUpsert {
+	u.Set(creditusage.FieldBeforeNumber, v)
+	return u
+}
+
+// UpdateBeforeNumber sets the "before_number" field to the value that was provided on create.
+func (u *CreditUsageUpsert) UpdateBeforeNumber() *CreditUsageUpsert {
+	u.SetExcluded(creditusage.FieldBeforeNumber)
+	return u
+}
+
+// AddBeforeNumber adds v to the "before_number" field.
+func (u *CreditUsageUpsert) AddBeforeNumber(v float64) *CreditUsageUpsert {
+	u.Add(creditusage.FieldBeforeNumber, v)
+	return u
+}
+
+// ClearBeforeNumber clears the value of the "before_number" field.
+func (u *CreditUsageUpsert) ClearBeforeNumber() *CreditUsageUpsert {
+	u.SetNull(creditusage.FieldBeforeNumber)
+	return u
+}
+
+// SetAfterNumber sets the "after_number" field.
+func (u *CreditUsageUpsert) SetAfterNumber(v float64) *CreditUsageUpsert {
+	u.Set(creditusage.FieldAfterNumber, v)
+	return u
+}
+
+// UpdateAfterNumber sets the "after_number" field to the value that was provided on create.
+func (u *CreditUsageUpsert) UpdateAfterNumber() *CreditUsageUpsert {
+	u.SetExcluded(creditusage.FieldAfterNumber)
+	return u
+}
+
+// AddAfterNumber adds v to the "after_number" field.
+func (u *CreditUsageUpsert) AddAfterNumber(v float64) *CreditUsageUpsert {
+	u.Add(creditusage.FieldAfterNumber, v)
+	return u
+}
+
+// ClearAfterNumber clears the value of the "after_number" field.
+func (u *CreditUsageUpsert) ClearAfterNumber() *CreditUsageUpsert {
+	u.SetNull(creditusage.FieldAfterNumber)
+	return u
+}
+
+// SetPayMethod sets the "pay_method" field.
+func (u *CreditUsageUpsert) SetPayMethod(v int) *CreditUsageUpsert {
+	u.Set(creditusage.FieldPayMethod, v)
+	return u
+}
+
+// UpdatePayMethod sets the "pay_method" field to the value that was provided on create.
+func (u *CreditUsageUpsert) UpdatePayMethod() *CreditUsageUpsert {
+	u.SetExcluded(creditusage.FieldPayMethod)
+	return u
+}
+
+// AddPayMethod adds v to the "pay_method" field.
+func (u *CreditUsageUpsert) AddPayMethod(v int) *CreditUsageUpsert {
+	u.Add(creditusage.FieldPayMethod, v)
+	return u
+}
+
+// ClearPayMethod clears the value of the "pay_method" field.
+func (u *CreditUsageUpsert) ClearPayMethod() *CreditUsageUpsert {
+	u.SetNull(creditusage.FieldPayMethod)
+	return u
+}
+
 // SetStatus sets the "status" field.
 func (u *CreditUsageUpsert) SetStatus(v int) *CreditUsageUpsert {
 	u.Set(creditusage.FieldStatus, v)
@@ -739,14 +911,14 @@ func (u *CreditUsageUpsertOne) ClearUserID() *CreditUsageUpsertOne {
 }
 
 // SetNumber sets the "number" field.
-func (u *CreditUsageUpsertOne) SetNumber(v float32) *CreditUsageUpsertOne {
+func (u *CreditUsageUpsertOne) SetNumber(v float64) *CreditUsageUpsertOne {
 	return u.Update(func(s *CreditUsageUpsert) {
 		s.SetNumber(v)
 	})
 }
 
 // AddNumber adds v to the "number" field.
-func (u *CreditUsageUpsertOne) AddNumber(v float32) *CreditUsageUpsertOne {
+func (u *CreditUsageUpsertOne) AddNumber(v float64) *CreditUsageUpsertOne {
 	return u.Update(func(s *CreditUsageUpsert) {
 		s.AddNumber(v)
 	})
@@ -759,6 +931,118 @@ func (u *CreditUsageUpsertOne) UpdateNumber() *CreditUsageUpsertOne {
 	})
 }
 
+// SetPayNumber sets the "pay_number" field.
+func (u *CreditUsageUpsertOne) SetPayNumber(v float64) *CreditUsageUpsertOne {
+	return u.Update(func(s *CreditUsageUpsert) {
+		s.SetPayNumber(v)
+	})
+}
+
+// AddPayNumber adds v to the "pay_number" field.
+func (u *CreditUsageUpsertOne) AddPayNumber(v float64) *CreditUsageUpsertOne {
+	return u.Update(func(s *CreditUsageUpsert) {
+		s.AddPayNumber(v)
+	})
+}
+
+// UpdatePayNumber sets the "pay_number" field to the value that was provided on create.
+func (u *CreditUsageUpsertOne) UpdatePayNumber() *CreditUsageUpsertOne {
+	return u.Update(func(s *CreditUsageUpsert) {
+		s.UpdatePayNumber()
+	})
+}
+
+// ClearPayNumber clears the value of the "pay_number" field.
+func (u *CreditUsageUpsertOne) ClearPayNumber() *CreditUsageUpsertOne {
+	return u.Update(func(s *CreditUsageUpsert) {
+		s.ClearPayNumber()
+	})
+}
+
+// SetBeforeNumber sets the "before_number" field.
+func (u *CreditUsageUpsertOne) SetBeforeNumber(v float64) *CreditUsageUpsertOne {
+	return u.Update(func(s *CreditUsageUpsert) {
+		s.SetBeforeNumber(v)
+	})
+}
+
+// AddBeforeNumber adds v to the "before_number" field.
+func (u *CreditUsageUpsertOne) AddBeforeNumber(v float64) *CreditUsageUpsertOne {
+	return u.Update(func(s *CreditUsageUpsert) {
+		s.AddBeforeNumber(v)
+	})
+}
+
+// UpdateBeforeNumber sets the "before_number" field to the value that was provided on create.
+func (u *CreditUsageUpsertOne) UpdateBeforeNumber() *CreditUsageUpsertOne {
+	return u.Update(func(s *CreditUsageUpsert) {
+		s.UpdateBeforeNumber()
+	})
+}
+
+// ClearBeforeNumber clears the value of the "before_number" field.
+func (u *CreditUsageUpsertOne) ClearBeforeNumber() *CreditUsageUpsertOne {
+	return u.Update(func(s *CreditUsageUpsert) {
+		s.ClearBeforeNumber()
+	})
+}
+
+// SetAfterNumber sets the "after_number" field.
+func (u *CreditUsageUpsertOne) SetAfterNumber(v float64) *CreditUsageUpsertOne {
+	return u.Update(func(s *CreditUsageUpsert) {
+		s.SetAfterNumber(v)
+	})
+}
+
+// AddAfterNumber adds v to the "after_number" field.
+func (u *CreditUsageUpsertOne) AddAfterNumber(v float64) *CreditUsageUpsertOne {
+	return u.Update(func(s *CreditUsageUpsert) {
+		s.AddAfterNumber(v)
+	})
+}
+
+// UpdateAfterNumber sets the "after_number" field to the value that was provided on create.
+func (u *CreditUsageUpsertOne) UpdateAfterNumber() *CreditUsageUpsertOne {
+	return u.Update(func(s *CreditUsageUpsert) {
+		s.UpdateAfterNumber()
+	})
+}
+
+// ClearAfterNumber clears the value of the "after_number" field.
+func (u *CreditUsageUpsertOne) ClearAfterNumber() *CreditUsageUpsertOne {
+	return u.Update(func(s *CreditUsageUpsert) {
+		s.ClearAfterNumber()
+	})
+}
+
+// SetPayMethod sets the "pay_method" field.
+func (u *CreditUsageUpsertOne) SetPayMethod(v int) *CreditUsageUpsertOne {
+	return u.Update(func(s *CreditUsageUpsert) {
+		s.SetPayMethod(v)
+	})
+}
+
+// AddPayMethod adds v to the "pay_method" field.
+func (u *CreditUsageUpsertOne) AddPayMethod(v int) *CreditUsageUpsertOne {
+	return u.Update(func(s *CreditUsageUpsert) {
+		s.AddPayMethod(v)
+	})
+}
+
+// UpdatePayMethod sets the "pay_method" field to the value that was provided on create.
+func (u *CreditUsageUpsertOne) UpdatePayMethod() *CreditUsageUpsertOne {
+	return u.Update(func(s *CreditUsageUpsert) {
+		s.UpdatePayMethod()
+	})
+}
+
+// ClearPayMethod clears the value of the "pay_method" field.
+func (u *CreditUsageUpsertOne) ClearPayMethod() *CreditUsageUpsertOne {
+	return u.Update(func(s *CreditUsageUpsert) {
+		s.ClearPayMethod()
+	})
+}
+
 // SetStatus sets the "status" field.
 func (u *CreditUsageUpsertOne) SetStatus(v int) *CreditUsageUpsertOne {
 	return u.Update(func(s *CreditUsageUpsert) {
@@ -1173,14 +1457,14 @@ func (u *CreditUsageUpsertBulk) ClearUserID() *CreditUsageUpsertBulk {
 }
 
 // SetNumber sets the "number" field.
-func (u *CreditUsageUpsertBulk) SetNumber(v float32) *CreditUsageUpsertBulk {
+func (u *CreditUsageUpsertBulk) SetNumber(v float64) *CreditUsageUpsertBulk {
 	return u.Update(func(s *CreditUsageUpsert) {
 		s.SetNumber(v)
 	})
 }
 
 // AddNumber adds v to the "number" field.
-func (u *CreditUsageUpsertBulk) AddNumber(v float32) *CreditUsageUpsertBulk {
+func (u *CreditUsageUpsertBulk) AddNumber(v float64) *CreditUsageUpsertBulk {
 	return u.Update(func(s *CreditUsageUpsert) {
 		s.AddNumber(v)
 	})
@@ -1193,6 +1477,118 @@ func (u *CreditUsageUpsertBulk) UpdateNumber() *CreditUsageUpsertBulk {
 	})
 }
 
+// SetPayNumber sets the "pay_number" field.
+func (u *CreditUsageUpsertBulk) SetPayNumber(v float64) *CreditUsageUpsertBulk {
+	return u.Update(func(s *CreditUsageUpsert) {
+		s.SetPayNumber(v)
+	})
+}
+
+// AddPayNumber adds v to the "pay_number" field.
+func (u *CreditUsageUpsertBulk) AddPayNumber(v float64) *CreditUsageUpsertBulk {
+	return u.Update(func(s *CreditUsageUpsert) {
+		s.AddPayNumber(v)
+	})
+}
+
+// UpdatePayNumber sets the "pay_number" field to the value that was provided on create.
+func (u *CreditUsageUpsertBulk) UpdatePayNumber() *CreditUsageUpsertBulk {
+	return u.Update(func(s *CreditUsageUpsert) {
+		s.UpdatePayNumber()
+	})
+}
+
+// ClearPayNumber clears the value of the "pay_number" field.
+func (u *CreditUsageUpsertBulk) ClearPayNumber() *CreditUsageUpsertBulk {
+	return u.Update(func(s *CreditUsageUpsert) {
+		s.ClearPayNumber()
+	})
+}
+
+// SetBeforeNumber sets the "before_number" field.
+func (u *CreditUsageUpsertBulk) SetBeforeNumber(v float64) *CreditUsageUpsertBulk {
+	return u.Update(func(s *CreditUsageUpsert) {
+		s.SetBeforeNumber(v)
+	})
+}
+
+// AddBeforeNumber adds v to the "before_number" field.
+func (u *CreditUsageUpsertBulk) AddBeforeNumber(v float64) *CreditUsageUpsertBulk {
+	return u.Update(func(s *CreditUsageUpsert) {
+		s.AddBeforeNumber(v)
+	})
+}
+
+// UpdateBeforeNumber sets the "before_number" field to the value that was provided on create.
+func (u *CreditUsageUpsertBulk) UpdateBeforeNumber() *CreditUsageUpsertBulk {
+	return u.Update(func(s *CreditUsageUpsert) {
+		s.UpdateBeforeNumber()
+	})
+}
+
+// ClearBeforeNumber clears the value of the "before_number" field.
+func (u *CreditUsageUpsertBulk) ClearBeforeNumber() *CreditUsageUpsertBulk {
+	return u.Update(func(s *CreditUsageUpsert) {
+		s.ClearBeforeNumber()
+	})
+}
+
+// SetAfterNumber sets the "after_number" field.
+func (u *CreditUsageUpsertBulk) SetAfterNumber(v float64) *CreditUsageUpsertBulk {
+	return u.Update(func(s *CreditUsageUpsert) {
+		s.SetAfterNumber(v)
+	})
+}
+
+// AddAfterNumber adds v to the "after_number" field.
+func (u *CreditUsageUpsertBulk) AddAfterNumber(v float64) *CreditUsageUpsertBulk {
+	return u.Update(func(s *CreditUsageUpsert) {
+		s.AddAfterNumber(v)
+	})
+}
+
+// UpdateAfterNumber sets the "after_number" field to the value that was provided on create.
+func (u *CreditUsageUpsertBulk) UpdateAfterNumber() *CreditUsageUpsertBulk {
+	return u.Update(func(s *CreditUsageUpsert) {
+		s.UpdateAfterNumber()
+	})
+}
+
+// ClearAfterNumber clears the value of the "after_number" field.
+func (u *CreditUsageUpsertBulk) ClearAfterNumber() *CreditUsageUpsertBulk {
+	return u.Update(func(s *CreditUsageUpsert) {
+		s.ClearAfterNumber()
+	})
+}
+
+// SetPayMethod sets the "pay_method" field.
+func (u *CreditUsageUpsertBulk) SetPayMethod(v int) *CreditUsageUpsertBulk {
+	return u.Update(func(s *CreditUsageUpsert) {
+		s.SetPayMethod(v)
+	})
+}
+
+// AddPayMethod adds v to the "pay_method" field.
+func (u *CreditUsageUpsertBulk) AddPayMethod(v int) *CreditUsageUpsertBulk {
+	return u.Update(func(s *CreditUsageUpsert) {
+		s.AddPayMethod(v)
+	})
+}
+
+// UpdatePayMethod sets the "pay_method" field to the value that was provided on create.
+func (u *CreditUsageUpsertBulk) UpdatePayMethod() *CreditUsageUpsertBulk {
+	return u.Update(func(s *CreditUsageUpsert) {
+		s.UpdatePayMethod()
+	})
+}
+
+// ClearPayMethod clears the value of the "pay_method" field.
+func (u *CreditUsageUpsertBulk) ClearPayMethod() *CreditUsageUpsertBulk {
+	return u.Update(func(s *CreditUsageUpsert) {
+		s.ClearPayMethod()
+	})
+}
+
 // SetStatus sets the "status" field.
 func (u *CreditUsageUpsertBulk) SetStatus(v int) *CreditUsageUpsertBulk {
 	return u.Update(func(s *CreditUsageUpsert) {

+ 298 - 10
ent/creditusage_update.go

@@ -75,14 +75,14 @@ func (cuu *CreditUsageUpdate) ClearUserID() *CreditUsageUpdate {
 }
 
 // SetNumber sets the "number" field.
-func (cuu *CreditUsageUpdate) SetNumber(f float32) *CreditUsageUpdate {
+func (cuu *CreditUsageUpdate) SetNumber(f float64) *CreditUsageUpdate {
 	cuu.mutation.ResetNumber()
 	cuu.mutation.SetNumber(f)
 	return cuu
 }
 
 // SetNillableNumber sets the "number" field if the given value is not nil.
-func (cuu *CreditUsageUpdate) SetNillableNumber(f *float32) *CreditUsageUpdate {
+func (cuu *CreditUsageUpdate) SetNillableNumber(f *float64) *CreditUsageUpdate {
 	if f != nil {
 		cuu.SetNumber(*f)
 	}
@@ -90,11 +90,119 @@ func (cuu *CreditUsageUpdate) SetNillableNumber(f *float32) *CreditUsageUpdate {
 }
 
 // AddNumber adds f to the "number" field.
-func (cuu *CreditUsageUpdate) AddNumber(f float32) *CreditUsageUpdate {
+func (cuu *CreditUsageUpdate) AddNumber(f float64) *CreditUsageUpdate {
 	cuu.mutation.AddNumber(f)
 	return cuu
 }
 
+// SetPayNumber sets the "pay_number" field.
+func (cuu *CreditUsageUpdate) SetPayNumber(f float64) *CreditUsageUpdate {
+	cuu.mutation.ResetPayNumber()
+	cuu.mutation.SetPayNumber(f)
+	return cuu
+}
+
+// SetNillablePayNumber sets the "pay_number" field if the given value is not nil.
+func (cuu *CreditUsageUpdate) SetNillablePayNumber(f *float64) *CreditUsageUpdate {
+	if f != nil {
+		cuu.SetPayNumber(*f)
+	}
+	return cuu
+}
+
+// AddPayNumber adds f to the "pay_number" field.
+func (cuu *CreditUsageUpdate) AddPayNumber(f float64) *CreditUsageUpdate {
+	cuu.mutation.AddPayNumber(f)
+	return cuu
+}
+
+// ClearPayNumber clears the value of the "pay_number" field.
+func (cuu *CreditUsageUpdate) ClearPayNumber() *CreditUsageUpdate {
+	cuu.mutation.ClearPayNumber()
+	return cuu
+}
+
+// SetBeforeNumber sets the "before_number" field.
+func (cuu *CreditUsageUpdate) SetBeforeNumber(f float64) *CreditUsageUpdate {
+	cuu.mutation.ResetBeforeNumber()
+	cuu.mutation.SetBeforeNumber(f)
+	return cuu
+}
+
+// SetNillableBeforeNumber sets the "before_number" field if the given value is not nil.
+func (cuu *CreditUsageUpdate) SetNillableBeforeNumber(f *float64) *CreditUsageUpdate {
+	if f != nil {
+		cuu.SetBeforeNumber(*f)
+	}
+	return cuu
+}
+
+// AddBeforeNumber adds f to the "before_number" field.
+func (cuu *CreditUsageUpdate) AddBeforeNumber(f float64) *CreditUsageUpdate {
+	cuu.mutation.AddBeforeNumber(f)
+	return cuu
+}
+
+// ClearBeforeNumber clears the value of the "before_number" field.
+func (cuu *CreditUsageUpdate) ClearBeforeNumber() *CreditUsageUpdate {
+	cuu.mutation.ClearBeforeNumber()
+	return cuu
+}
+
+// SetAfterNumber sets the "after_number" field.
+func (cuu *CreditUsageUpdate) SetAfterNumber(f float64) *CreditUsageUpdate {
+	cuu.mutation.ResetAfterNumber()
+	cuu.mutation.SetAfterNumber(f)
+	return cuu
+}
+
+// SetNillableAfterNumber sets the "after_number" field if the given value is not nil.
+func (cuu *CreditUsageUpdate) SetNillableAfterNumber(f *float64) *CreditUsageUpdate {
+	if f != nil {
+		cuu.SetAfterNumber(*f)
+	}
+	return cuu
+}
+
+// AddAfterNumber adds f to the "after_number" field.
+func (cuu *CreditUsageUpdate) AddAfterNumber(f float64) *CreditUsageUpdate {
+	cuu.mutation.AddAfterNumber(f)
+	return cuu
+}
+
+// ClearAfterNumber clears the value of the "after_number" field.
+func (cuu *CreditUsageUpdate) ClearAfterNumber() *CreditUsageUpdate {
+	cuu.mutation.ClearAfterNumber()
+	return cuu
+}
+
+// SetPayMethod sets the "pay_method" field.
+func (cuu *CreditUsageUpdate) SetPayMethod(i int) *CreditUsageUpdate {
+	cuu.mutation.ResetPayMethod()
+	cuu.mutation.SetPayMethod(i)
+	return cuu
+}
+
+// SetNillablePayMethod sets the "pay_method" field if the given value is not nil.
+func (cuu *CreditUsageUpdate) SetNillablePayMethod(i *int) *CreditUsageUpdate {
+	if i != nil {
+		cuu.SetPayMethod(*i)
+	}
+	return cuu
+}
+
+// AddPayMethod adds i to the "pay_method" field.
+func (cuu *CreditUsageUpdate) AddPayMethod(i int) *CreditUsageUpdate {
+	cuu.mutation.AddPayMethod(i)
+	return cuu
+}
+
+// ClearPayMethod clears the value of the "pay_method" field.
+func (cuu *CreditUsageUpdate) ClearPayMethod() *CreditUsageUpdate {
+	cuu.mutation.ClearPayMethod()
+	return cuu
+}
+
 // SetStatus sets the "status" field.
 func (cuu *CreditUsageUpdate) SetStatus(i int) *CreditUsageUpdate {
 	cuu.mutation.ResetStatus()
@@ -333,10 +441,46 @@ func (cuu *CreditUsageUpdate) sqlSave(ctx context.Context) (n int, err error) {
 		_spec.ClearField(creditusage.FieldUserID, field.TypeString)
 	}
 	if value, ok := cuu.mutation.Number(); ok {
-		_spec.SetField(creditusage.FieldNumber, field.TypeFloat32, value)
+		_spec.SetField(creditusage.FieldNumber, field.TypeFloat64, value)
 	}
 	if value, ok := cuu.mutation.AddedNumber(); ok {
-		_spec.AddField(creditusage.FieldNumber, field.TypeFloat32, value)
+		_spec.AddField(creditusage.FieldNumber, field.TypeFloat64, value)
+	}
+	if value, ok := cuu.mutation.PayNumber(); ok {
+		_spec.SetField(creditusage.FieldPayNumber, field.TypeFloat64, value)
+	}
+	if value, ok := cuu.mutation.AddedPayNumber(); ok {
+		_spec.AddField(creditusage.FieldPayNumber, field.TypeFloat64, value)
+	}
+	if cuu.mutation.PayNumberCleared() {
+		_spec.ClearField(creditusage.FieldPayNumber, field.TypeFloat64)
+	}
+	if value, ok := cuu.mutation.BeforeNumber(); ok {
+		_spec.SetField(creditusage.FieldBeforeNumber, field.TypeFloat64, value)
+	}
+	if value, ok := cuu.mutation.AddedBeforeNumber(); ok {
+		_spec.AddField(creditusage.FieldBeforeNumber, field.TypeFloat64, value)
+	}
+	if cuu.mutation.BeforeNumberCleared() {
+		_spec.ClearField(creditusage.FieldBeforeNumber, field.TypeFloat64)
+	}
+	if value, ok := cuu.mutation.AfterNumber(); ok {
+		_spec.SetField(creditusage.FieldAfterNumber, field.TypeFloat64, value)
+	}
+	if value, ok := cuu.mutation.AddedAfterNumber(); ok {
+		_spec.AddField(creditusage.FieldAfterNumber, field.TypeFloat64, value)
+	}
+	if cuu.mutation.AfterNumberCleared() {
+		_spec.ClearField(creditusage.FieldAfterNumber, field.TypeFloat64)
+	}
+	if value, ok := cuu.mutation.PayMethod(); ok {
+		_spec.SetField(creditusage.FieldPayMethod, field.TypeInt, value)
+	}
+	if value, ok := cuu.mutation.AddedPayMethod(); ok {
+		_spec.AddField(creditusage.FieldPayMethod, field.TypeInt, value)
+	}
+	if cuu.mutation.PayMethodCleared() {
+		_spec.ClearField(creditusage.FieldPayMethod, field.TypeInt)
 	}
 	if value, ok := cuu.mutation.Status(); ok {
 		_spec.SetField(creditusage.FieldStatus, field.TypeInt, value)
@@ -444,14 +588,14 @@ func (cuuo *CreditUsageUpdateOne) ClearUserID() *CreditUsageUpdateOne {
 }
 
 // SetNumber sets the "number" field.
-func (cuuo *CreditUsageUpdateOne) SetNumber(f float32) *CreditUsageUpdateOne {
+func (cuuo *CreditUsageUpdateOne) SetNumber(f float64) *CreditUsageUpdateOne {
 	cuuo.mutation.ResetNumber()
 	cuuo.mutation.SetNumber(f)
 	return cuuo
 }
 
 // SetNillableNumber sets the "number" field if the given value is not nil.
-func (cuuo *CreditUsageUpdateOne) SetNillableNumber(f *float32) *CreditUsageUpdateOne {
+func (cuuo *CreditUsageUpdateOne) SetNillableNumber(f *float64) *CreditUsageUpdateOne {
 	if f != nil {
 		cuuo.SetNumber(*f)
 	}
@@ -459,11 +603,119 @@ func (cuuo *CreditUsageUpdateOne) SetNillableNumber(f *float32) *CreditUsageUpda
 }
 
 // AddNumber adds f to the "number" field.
-func (cuuo *CreditUsageUpdateOne) AddNumber(f float32) *CreditUsageUpdateOne {
+func (cuuo *CreditUsageUpdateOne) AddNumber(f float64) *CreditUsageUpdateOne {
 	cuuo.mutation.AddNumber(f)
 	return cuuo
 }
 
+// SetPayNumber sets the "pay_number" field.
+func (cuuo *CreditUsageUpdateOne) SetPayNumber(f float64) *CreditUsageUpdateOne {
+	cuuo.mutation.ResetPayNumber()
+	cuuo.mutation.SetPayNumber(f)
+	return cuuo
+}
+
+// SetNillablePayNumber sets the "pay_number" field if the given value is not nil.
+func (cuuo *CreditUsageUpdateOne) SetNillablePayNumber(f *float64) *CreditUsageUpdateOne {
+	if f != nil {
+		cuuo.SetPayNumber(*f)
+	}
+	return cuuo
+}
+
+// AddPayNumber adds f to the "pay_number" field.
+func (cuuo *CreditUsageUpdateOne) AddPayNumber(f float64) *CreditUsageUpdateOne {
+	cuuo.mutation.AddPayNumber(f)
+	return cuuo
+}
+
+// ClearPayNumber clears the value of the "pay_number" field.
+func (cuuo *CreditUsageUpdateOne) ClearPayNumber() *CreditUsageUpdateOne {
+	cuuo.mutation.ClearPayNumber()
+	return cuuo
+}
+
+// SetBeforeNumber sets the "before_number" field.
+func (cuuo *CreditUsageUpdateOne) SetBeforeNumber(f float64) *CreditUsageUpdateOne {
+	cuuo.mutation.ResetBeforeNumber()
+	cuuo.mutation.SetBeforeNumber(f)
+	return cuuo
+}
+
+// SetNillableBeforeNumber sets the "before_number" field if the given value is not nil.
+func (cuuo *CreditUsageUpdateOne) SetNillableBeforeNumber(f *float64) *CreditUsageUpdateOne {
+	if f != nil {
+		cuuo.SetBeforeNumber(*f)
+	}
+	return cuuo
+}
+
+// AddBeforeNumber adds f to the "before_number" field.
+func (cuuo *CreditUsageUpdateOne) AddBeforeNumber(f float64) *CreditUsageUpdateOne {
+	cuuo.mutation.AddBeforeNumber(f)
+	return cuuo
+}
+
+// ClearBeforeNumber clears the value of the "before_number" field.
+func (cuuo *CreditUsageUpdateOne) ClearBeforeNumber() *CreditUsageUpdateOne {
+	cuuo.mutation.ClearBeforeNumber()
+	return cuuo
+}
+
+// SetAfterNumber sets the "after_number" field.
+func (cuuo *CreditUsageUpdateOne) SetAfterNumber(f float64) *CreditUsageUpdateOne {
+	cuuo.mutation.ResetAfterNumber()
+	cuuo.mutation.SetAfterNumber(f)
+	return cuuo
+}
+
+// SetNillableAfterNumber sets the "after_number" field if the given value is not nil.
+func (cuuo *CreditUsageUpdateOne) SetNillableAfterNumber(f *float64) *CreditUsageUpdateOne {
+	if f != nil {
+		cuuo.SetAfterNumber(*f)
+	}
+	return cuuo
+}
+
+// AddAfterNumber adds f to the "after_number" field.
+func (cuuo *CreditUsageUpdateOne) AddAfterNumber(f float64) *CreditUsageUpdateOne {
+	cuuo.mutation.AddAfterNumber(f)
+	return cuuo
+}
+
+// ClearAfterNumber clears the value of the "after_number" field.
+func (cuuo *CreditUsageUpdateOne) ClearAfterNumber() *CreditUsageUpdateOne {
+	cuuo.mutation.ClearAfterNumber()
+	return cuuo
+}
+
+// SetPayMethod sets the "pay_method" field.
+func (cuuo *CreditUsageUpdateOne) SetPayMethod(i int) *CreditUsageUpdateOne {
+	cuuo.mutation.ResetPayMethod()
+	cuuo.mutation.SetPayMethod(i)
+	return cuuo
+}
+
+// SetNillablePayMethod sets the "pay_method" field if the given value is not nil.
+func (cuuo *CreditUsageUpdateOne) SetNillablePayMethod(i *int) *CreditUsageUpdateOne {
+	if i != nil {
+		cuuo.SetPayMethod(*i)
+	}
+	return cuuo
+}
+
+// AddPayMethod adds i to the "pay_method" field.
+func (cuuo *CreditUsageUpdateOne) AddPayMethod(i int) *CreditUsageUpdateOne {
+	cuuo.mutation.AddPayMethod(i)
+	return cuuo
+}
+
+// ClearPayMethod clears the value of the "pay_method" field.
+func (cuuo *CreditUsageUpdateOne) ClearPayMethod() *CreditUsageUpdateOne {
+	cuuo.mutation.ClearPayMethod()
+	return cuuo
+}
+
 // SetStatus sets the "status" field.
 func (cuuo *CreditUsageUpdateOne) SetStatus(i int) *CreditUsageUpdateOne {
 	cuuo.mutation.ResetStatus()
@@ -732,10 +984,46 @@ func (cuuo *CreditUsageUpdateOne) sqlSave(ctx context.Context) (_node *CreditUsa
 		_spec.ClearField(creditusage.FieldUserID, field.TypeString)
 	}
 	if value, ok := cuuo.mutation.Number(); ok {
-		_spec.SetField(creditusage.FieldNumber, field.TypeFloat32, value)
+		_spec.SetField(creditusage.FieldNumber, field.TypeFloat64, value)
 	}
 	if value, ok := cuuo.mutation.AddedNumber(); ok {
-		_spec.AddField(creditusage.FieldNumber, field.TypeFloat32, value)
+		_spec.AddField(creditusage.FieldNumber, field.TypeFloat64, value)
+	}
+	if value, ok := cuuo.mutation.PayNumber(); ok {
+		_spec.SetField(creditusage.FieldPayNumber, field.TypeFloat64, value)
+	}
+	if value, ok := cuuo.mutation.AddedPayNumber(); ok {
+		_spec.AddField(creditusage.FieldPayNumber, field.TypeFloat64, value)
+	}
+	if cuuo.mutation.PayNumberCleared() {
+		_spec.ClearField(creditusage.FieldPayNumber, field.TypeFloat64)
+	}
+	if value, ok := cuuo.mutation.BeforeNumber(); ok {
+		_spec.SetField(creditusage.FieldBeforeNumber, field.TypeFloat64, value)
+	}
+	if value, ok := cuuo.mutation.AddedBeforeNumber(); ok {
+		_spec.AddField(creditusage.FieldBeforeNumber, field.TypeFloat64, value)
+	}
+	if cuuo.mutation.BeforeNumberCleared() {
+		_spec.ClearField(creditusage.FieldBeforeNumber, field.TypeFloat64)
+	}
+	if value, ok := cuuo.mutation.AfterNumber(); ok {
+		_spec.SetField(creditusage.FieldAfterNumber, field.TypeFloat64, value)
+	}
+	if value, ok := cuuo.mutation.AddedAfterNumber(); ok {
+		_spec.AddField(creditusage.FieldAfterNumber, field.TypeFloat64, value)
+	}
+	if cuuo.mutation.AfterNumberCleared() {
+		_spec.ClearField(creditusage.FieldAfterNumber, field.TypeFloat64)
+	}
+	if value, ok := cuuo.mutation.PayMethod(); ok {
+		_spec.SetField(creditusage.FieldPayMethod, field.TypeInt, value)
+	}
+	if value, ok := cuuo.mutation.AddedPayMethod(); ok {
+		_spec.AddField(creditusage.FieldPayMethod, field.TypeInt, value)
+	}
+	if cuuo.mutation.PayMethodCleared() {
+		_spec.ClearField(creditusage.FieldPayMethod, field.TypeInt)
 	}
 	if value, ok := cuuo.mutation.Status(); ok {
 		_spec.SetField(creditusage.FieldStatus, field.TypeInt, value)

+ 4 - 0
ent/ent.go

@@ -53,6 +53,8 @@ import (
 	"wechat-api/ent/wxcard"
 	"wechat-api/ent/wxcarduser"
 	"wechat-api/ent/wxcardvisit"
+	"wechat-api/ent/xunji"
+	"wechat-api/ent/xunjiservice"
 
 	"entgo.io/ent"
 	"entgo.io/ent/dialect/sql"
@@ -162,6 +164,8 @@ func checkColumn(table, column string) error {
 			wxcard.Table:               wxcard.ValidColumn,
 			wxcarduser.Table:           wxcarduser.ValidColumn,
 			wxcardvisit.Table:          wxcardvisit.ValidColumn,
+			xunji.Table:                xunji.ValidColumn,
+			xunjiservice.Table:         xunjiservice.ValidColumn,
 		})
 	})
 	return columnCheck(table, column)

+ 24 - 0
ent/hook/hook.go

@@ -548,6 +548,30 @@ func (f WxCardVisitFunc) Mutate(ctx context.Context, m ent.Mutation) (ent.Value,
 	return nil, fmt.Errorf("unexpected mutation type %T. expect *ent.WxCardVisitMutation", m)
 }
 
+// The XunjiFunc type is an adapter to allow the use of ordinary
+// function as Xunji mutator.
+type XunjiFunc func(context.Context, *ent.XunjiMutation) (ent.Value, error)
+
+// Mutate calls f(ctx, m).
+func (f XunjiFunc) Mutate(ctx context.Context, m ent.Mutation) (ent.Value, error) {
+	if mv, ok := m.(*ent.XunjiMutation); ok {
+		return f(ctx, mv)
+	}
+	return nil, fmt.Errorf("unexpected mutation type %T. expect *ent.XunjiMutation", m)
+}
+
+// The XunjiServiceFunc type is an adapter to allow the use of ordinary
+// function as XunjiService mutator.
+type XunjiServiceFunc func(context.Context, *ent.XunjiServiceMutation) (ent.Value, error)
+
+// Mutate calls f(ctx, m).
+func (f XunjiServiceFunc) Mutate(ctx context.Context, m ent.Mutation) (ent.Value, error) {
+	if mv, ok := m.(*ent.XunjiServiceMutation); ok {
+		return f(ctx, mv)
+	}
+	return nil, fmt.Errorf("unexpected mutation type %T. expect *ent.XunjiServiceMutation", m)
+}
+
 // Condition is a hook condition function.
 type Condition func(context.Context, ent.Mutation) bool
 

+ 60 - 0
ent/intercept/intercept.go

@@ -52,6 +52,8 @@ import (
 	"wechat-api/ent/wxcard"
 	"wechat-api/ent/wxcarduser"
 	"wechat-api/ent/wxcardvisit"
+	"wechat-api/ent/xunji"
+	"wechat-api/ent/xunjiservice"
 
 	"entgo.io/ent/dialect/sql"
 )
@@ -1327,6 +1329,60 @@ func (f TraverseWxCardVisit) Traverse(ctx context.Context, q ent.Query) error {
 	return fmt.Errorf("unexpected query type %T. expect *ent.WxCardVisitQuery", q)
 }
 
+// The XunjiFunc type is an adapter to allow the use of ordinary function as a Querier.
+type XunjiFunc func(context.Context, *ent.XunjiQuery) (ent.Value, error)
+
+// Query calls f(ctx, q).
+func (f XunjiFunc) Query(ctx context.Context, q ent.Query) (ent.Value, error) {
+	if q, ok := q.(*ent.XunjiQuery); ok {
+		return f(ctx, q)
+	}
+	return nil, fmt.Errorf("unexpected query type %T. expect *ent.XunjiQuery", q)
+}
+
+// The TraverseXunji type is an adapter to allow the use of ordinary function as Traverser.
+type TraverseXunji func(context.Context, *ent.XunjiQuery) error
+
+// Intercept is a dummy implementation of Intercept that returns the next Querier in the pipeline.
+func (f TraverseXunji) Intercept(next ent.Querier) ent.Querier {
+	return next
+}
+
+// Traverse calls f(ctx, q).
+func (f TraverseXunji) Traverse(ctx context.Context, q ent.Query) error {
+	if q, ok := q.(*ent.XunjiQuery); ok {
+		return f(ctx, q)
+	}
+	return fmt.Errorf("unexpected query type %T. expect *ent.XunjiQuery", q)
+}
+
+// The XunjiServiceFunc type is an adapter to allow the use of ordinary function as a Querier.
+type XunjiServiceFunc func(context.Context, *ent.XunjiServiceQuery) (ent.Value, error)
+
+// Query calls f(ctx, q).
+func (f XunjiServiceFunc) Query(ctx context.Context, q ent.Query) (ent.Value, error) {
+	if q, ok := q.(*ent.XunjiServiceQuery); ok {
+		return f(ctx, q)
+	}
+	return nil, fmt.Errorf("unexpected query type %T. expect *ent.XunjiServiceQuery", q)
+}
+
+// The TraverseXunjiService type is an adapter to allow the use of ordinary function as Traverser.
+type TraverseXunjiService func(context.Context, *ent.XunjiServiceQuery) error
+
+// Intercept is a dummy implementation of Intercept that returns the next Querier in the pipeline.
+func (f TraverseXunjiService) Intercept(next ent.Querier) ent.Querier {
+	return next
+}
+
+// Traverse calls f(ctx, q).
+func (f TraverseXunjiService) Traverse(ctx context.Context, q ent.Query) error {
+	if q, ok := q.(*ent.XunjiServiceQuery); ok {
+		return f(ctx, q)
+	}
+	return fmt.Errorf("unexpected query type %T. expect *ent.XunjiServiceQuery", q)
+}
+
 // NewQuery returns the generic Query interface for the given typed query.
 func NewQuery(q ent.Query) (Query, error) {
 	switch q := q.(type) {
@@ -1420,6 +1476,10 @@ func NewQuery(q ent.Query) (Query, error) {
 		return &query[*ent.WxCardUserQuery, predicate.WxCardUser, wxcarduser.OrderOption]{typ: ent.TypeWxCardUser, tq: q}, nil
 	case *ent.WxCardVisitQuery:
 		return &query[*ent.WxCardVisitQuery, predicate.WxCardVisit, wxcardvisit.OrderOption]{typ: ent.TypeWxCardVisit, tq: q}, nil
+	case *ent.XunjiQuery:
+		return &query[*ent.XunjiQuery, predicate.Xunji, xunji.OrderOption]{typ: ent.TypeXunji, tq: q}, nil
+	case *ent.XunjiServiceQuery:
+		return &query[*ent.XunjiServiceQuery, predicate.XunjiService, xunjiservice.OrderOption]{typ: ent.TypeXunjiService, tq: q}, nil
 	default:
 		return nil, fmt.Errorf("unknown query type %T", q)
 	}

+ 87 - 3
ent/migrate/schema.go

@@ -421,7 +421,7 @@ var (
 		{Name: "updated_at", Type: field.TypeTime, Comment: "Update Time | 修改日期"},
 		{Name: "deleted_at", Type: field.TypeTime, Nullable: true, Comment: "Delete Time | 删除日期"},
 		{Name: "user_id", Type: field.TypeString, Nullable: true, Comment: "user_id | 用户ID"},
-		{Name: "balance", Type: field.TypeFloat32, Comment: "role | 角色设定"},
+		{Name: "balance", Type: field.TypeFloat64, Comment: "balance | 积分余额"},
 		{Name: "status", Type: field.TypeInt, Nullable: true, Comment: "status | 状态 1-正常 2-禁用", Default: 1},
 		{Name: "organization_id", Type: field.TypeUint64, Nullable: true, Comment: "organization_id | 租户ID"},
 	}
@@ -450,7 +450,11 @@ var (
 		{Name: "updated_at", Type: field.TypeTime, Comment: "Update Time | 修改日期"},
 		{Name: "deleted_at", Type: field.TypeTime, Nullable: true, Comment: "Delete Time | 删除日期"},
 		{Name: "user_id", Type: field.TypeString, Nullable: true, Size: 255, Comment: "user_id | 用户ID"},
-		{Name: "number", Type: field.TypeFloat32, Comment: "number | 积分改变量"},
+		{Name: "number", Type: field.TypeFloat64, Comment: "number | 积分改变量"},
+		{Name: "pay_number", Type: field.TypeFloat64, Nullable: true, Comment: "pay_number | 充值金额"},
+		{Name: "before_number", Type: field.TypeFloat64, Nullable: true, Comment: "before_number | 变动前金额"},
+		{Name: "after_number", Type: field.TypeFloat64, Nullable: true, Comment: "after_number | 变动后金额"},
+		{Name: "pay_method", Type: field.TypeInt, Nullable: true, Comment: "pay_method | 充值方式", Default: 1},
 		{Name: "status", Type: field.TypeInt, Nullable: true, Comment: "status | 状态 1-正常 2-禁用", Default: 1},
 		{Name: "ntype", Type: field.TypeInt, Comment: "ntype | 积分变化类型:1-消耗 2-增加", Default: 1},
 		{Name: "table", Type: field.TypeString, Comment: "table | 积分变化表名", Default: ""},
@@ -468,7 +472,7 @@ var (
 			{
 				Name:    "creditusage_organization_id",
 				Unique:  false,
-				Columns: []*schema.Column{CreditUsageColumns[9]},
+				Columns: []*schema.Column{CreditUsageColumns[13]},
 			},
 		},
 	}
@@ -1012,6 +1016,8 @@ var (
 		{Name: "prompt_tokens", Type: field.TypeUint64, Nullable: true, Comment: "请求token数", Default: 0},
 		{Name: "completion_tokens", Type: field.TypeUint64, Nullable: true, Comment: "响应token数", Default: 0},
 		{Name: "organization_id", Type: field.TypeUint64, Nullable: true, Comment: "机构 ID", Default: 1},
+		{Name: "model", Type: field.TypeString, Nullable: true, Comment: "模型", Default: "GPT-4o mini"},
+		{Name: "credits", Type: field.TypeFloat64, Nullable: true, Comment: "coins | 积分消耗数"},
 	}
 	// UsageDetailTable holds the schema information for the "usage_detail" table.
 	UsageDetailTable = &schema.Table{
@@ -1051,6 +1057,7 @@ var (
 		{Name: "active_user", Type: field.TypeUint64, Comment: "活跃用户数"},
 		{Name: "new_user", Type: field.TypeInt64, Comment: "新增用户数"},
 		{Name: "label_dist", Type: field.TypeJSON, Comment: "标签分布"},
+		{Name: "consume_coin", Type: field.TypeFloat64, Nullable: true, Comment: "消耗积分", Default: 0},
 	}
 	// UsageStatisticDayTable holds the schema information for the "usage_statistic_day" table.
 	UsageStatisticDayTable = &schema.Table{
@@ -1090,6 +1097,7 @@ var (
 		{Name: "active_user", Type: field.TypeUint64, Comment: "活跃用户数"},
 		{Name: "new_user", Type: field.TypeInt64, Comment: "新增用户数"},
 		{Name: "label_dist", Type: field.TypeJSON, Comment: "标签分布"},
+		{Name: "consume_coin", Type: field.TypeFloat64, Nullable: true, Comment: "消耗积分", Default: 0},
 	}
 	// UsageStatisticHourTable holds the schema information for the "usage_statistic_hour" table.
 	UsageStatisticHourTable = &schema.Table{
@@ -1129,6 +1137,7 @@ var (
 		{Name: "active_user", Type: field.TypeUint64, Comment: "活跃用户数"},
 		{Name: "new_user", Type: field.TypeInt64, Comment: "新增用户数"},
 		{Name: "label_dist", Type: field.TypeJSON, Comment: "标签分布"},
+		{Name: "consume_coin", Type: field.TypeFloat64, Nullable: true, Comment: "消耗积分", Default: 0},
 	}
 	// UsageStatisticMonthTable holds the schema information for the "usage_statistic_month" table.
 	UsageStatisticMonthTable = &schema.Table{
@@ -1509,6 +1518,72 @@ var (
 			},
 		},
 	}
+	// XunjiColumns holds the columns for the "xunji" table.
+	XunjiColumns = []*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: "app_key", Type: field.TypeString, Nullable: true, Comment: "AppKey"},
+		{Name: "app_secret", Type: field.TypeString, Nullable: true, Comment: "AppSecret"},
+		{Name: "token", Type: field.TypeString, Nullable: true, Comment: "Token"},
+		{Name: "encoding_key", Type: field.TypeString, Nullable: true, Comment: "加密key"},
+		{Name: "organization_id", Type: field.TypeUint64, Comment: "organization_id | 租户ID"},
+	}
+	// XunjiTable holds the schema information for the "xunji" table.
+	XunjiTable = &schema.Table{
+		Name:       "xunji",
+		Columns:    XunjiColumns,
+		PrimaryKey: []*schema.Column{XunjiColumns[0]},
+		Indexes: []*schema.Index{
+			{
+				Name:    "xunji_app_key_token",
+				Unique:  false,
+				Columns: []*schema.Column{XunjiColumns[5], XunjiColumns[7]},
+			},
+		},
+	}
+	// XunjiServiceColumns holds the columns for the "xunji_service" table.
+	XunjiServiceColumns = []*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: "xunji_id", Type: field.TypeUint64, Comment: "Xunji表ID"},
+		{Name: "organization_id", Type: field.TypeUint64, Comment: "organization_id | 租户ID"},
+		{Name: "wxid", Type: field.TypeString, Comment: "微信ID"},
+		{Name: "api_base", Type: field.TypeString, Nullable: true, Comment: "大模型服务地址", Default: ""},
+		{Name: "api_key", Type: field.TypeString, Nullable: true, Comment: "大模型服务密钥", Default: ""},
+		{Name: "agent_id", Type: field.TypeUint64, Comment: "智能体ID", Default: 0},
+	}
+	// XunjiServiceTable holds the schema information for the "xunji_service" table.
+	XunjiServiceTable = &schema.Table{
+		Name:       "xunji_service",
+		Columns:    XunjiServiceColumns,
+		PrimaryKey: []*schema.Column{XunjiServiceColumns[0]},
+		ForeignKeys: []*schema.ForeignKey{
+			{
+				Symbol:     "xunji_service_agent_xjs_agent",
+				Columns:    []*schema.Column{XunjiServiceColumns[10]},
+				RefColumns: []*schema.Column{AgentColumns[0]},
+				OnDelete:   schema.NoAction,
+			},
+		},
+		Indexes: []*schema.Index{
+			{
+				Name:    "xunjiservice_xunji_id",
+				Unique:  false,
+				Columns: []*schema.Column{XunjiServiceColumns[5]},
+			},
+			{
+				Name:    "xunjiservice_wxid",
+				Unique:  false,
+				Columns: []*schema.Column{XunjiServiceColumns[7]},
+			},
+		},
+	}
 	// Tables holds all the tables in the schema.
 	Tables = []*schema.Table{
 		AgentTable,
@@ -1556,6 +1631,8 @@ var (
 		WxCardTable,
 		WxCardUserTable,
 		WxCardVisitTable,
+		XunjiTable,
+		XunjiServiceTable,
 	}
 )
 
@@ -1711,4 +1788,11 @@ func init() {
 	WxCardVisitTable.Annotation = &entsql.Annotation{
 		Table: "wx_card_visit",
 	}
+	XunjiTable.Annotation = &entsql.Annotation{
+		Table: "xunji",
+	}
+	XunjiServiceTable.ForeignKeys[0].RefTable = AgentTable
+	XunjiServiceTable.Annotation = &entsql.Annotation{
+		Table: "xunji_service",
+	}
 }

Diferenças do arquivo suprimidas por serem muito extensas
+ 666 - 23
ent/mutation.go


+ 164 - 0
ent/pagination.go

@@ -50,6 +50,8 @@ import (
 	"wechat-api/ent/wxcard"
 	"wechat-api/ent/wxcarduser"
 	"wechat-api/ent/wxcardvisit"
+	"wechat-api/ent/xunji"
+	"wechat-api/ent/xunjiservice"
 )
 
 const errInvalidPage = "INVALID_PAGE"
@@ -3742,3 +3744,165 @@ func (wcv *WxCardVisitQuery) Page(
 
 	return ret, nil
 }
+
+type XunjiPager struct {
+	Order  xunji.OrderOption
+	Filter func(*XunjiQuery) (*XunjiQuery, error)
+}
+
+// XunjiPaginateOption enables pagination customization.
+type XunjiPaginateOption func(*XunjiPager)
+
+// DefaultXunjiOrder is the default ordering of Xunji.
+var DefaultXunjiOrder = Desc(xunji.FieldID)
+
+func newXunjiPager(opts []XunjiPaginateOption) (*XunjiPager, error) {
+	pager := &XunjiPager{}
+	for _, opt := range opts {
+		opt(pager)
+	}
+	if pager.Order == nil {
+		pager.Order = DefaultXunjiOrder
+	}
+	return pager, nil
+}
+
+func (p *XunjiPager) ApplyFilter(query *XunjiQuery) (*XunjiQuery, error) {
+	if p.Filter != nil {
+		return p.Filter(query)
+	}
+	return query, nil
+}
+
+// XunjiPageList is Xunji PageList result.
+type XunjiPageList struct {
+	List        []*Xunji     `json:"list"`
+	PageDetails *PageDetails `json:"pageDetails"`
+}
+
+func (x *XunjiQuery) Page(
+	ctx context.Context, pageNum uint64, pageSize uint64, opts ...XunjiPaginateOption,
+) (*XunjiPageList, error) {
+
+	pager, err := newXunjiPager(opts)
+	if err != nil {
+		return nil, err
+	}
+
+	if x, err = pager.ApplyFilter(x); err != nil {
+		return nil, err
+	}
+
+	ret := &XunjiPageList{}
+
+	ret.PageDetails = &PageDetails{
+		Page: pageNum,
+		Size: pageSize,
+	}
+
+	query := x.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 {
+		x = x.Order(pager.Order)
+	} else {
+		x = x.Order(DefaultXunjiOrder)
+	}
+
+	x = x.Offset(int((pageNum - 1) * pageSize)).Limit(int(pageSize))
+	list, err := x.All(ctx)
+	if err != nil {
+		return nil, err
+	}
+	ret.List = list
+
+	return ret, nil
+}
+
+type XunjiServicePager struct {
+	Order  xunjiservice.OrderOption
+	Filter func(*XunjiServiceQuery) (*XunjiServiceQuery, error)
+}
+
+// XunjiServicePaginateOption enables pagination customization.
+type XunjiServicePaginateOption func(*XunjiServicePager)
+
+// DefaultXunjiServiceOrder is the default ordering of XunjiService.
+var DefaultXunjiServiceOrder = Desc(xunjiservice.FieldID)
+
+func newXunjiServicePager(opts []XunjiServicePaginateOption) (*XunjiServicePager, error) {
+	pager := &XunjiServicePager{}
+	for _, opt := range opts {
+		opt(pager)
+	}
+	if pager.Order == nil {
+		pager.Order = DefaultXunjiServiceOrder
+	}
+	return pager, nil
+}
+
+func (p *XunjiServicePager) ApplyFilter(query *XunjiServiceQuery) (*XunjiServiceQuery, error) {
+	if p.Filter != nil {
+		return p.Filter(query)
+	}
+	return query, nil
+}
+
+// XunjiServicePageList is XunjiService PageList result.
+type XunjiServicePageList struct {
+	List        []*XunjiService `json:"list"`
+	PageDetails *PageDetails    `json:"pageDetails"`
+}
+
+func (xs *XunjiServiceQuery) Page(
+	ctx context.Context, pageNum uint64, pageSize uint64, opts ...XunjiServicePaginateOption,
+) (*XunjiServicePageList, error) {
+
+	pager, err := newXunjiServicePager(opts)
+	if err != nil {
+		return nil, err
+	}
+
+	if xs, err = pager.ApplyFilter(xs); err != nil {
+		return nil, err
+	}
+
+	ret := &XunjiServicePageList{}
+
+	ret.PageDetails = &PageDetails{
+		Page: pageNum,
+		Size: pageSize,
+	}
+
+	query := xs.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 {
+		xs = xs.Order(pager.Order)
+	} else {
+		xs = xs.Order(DefaultXunjiServiceOrder)
+	}
+
+	xs = xs.Offset(int((pageNum - 1) * pageSize)).Limit(int(pageSize))
+	list, err := xs.All(ctx)
+	if err != nil {
+		return nil, err
+	}
+	ret.List = list
+
+	return ret, nil
+}

+ 6 - 0
ent/predicate/predicate.go

@@ -140,3 +140,9 @@ type WxCardUser func(*sql.Selector)
 
 // WxCardVisit is the predicate function for wxcardvisit builders.
 type WxCardVisit func(*sql.Selector)
+
+// Xunji is the predicate function for xunji builders.
+type Xunji func(*sql.Selector)
+
+// XunjiService is the predicate function for xunjiservice builders.
+type XunjiService func(*sql.Selector)

+ 98 - 6
ent/runtime/runtime.go

@@ -50,6 +50,8 @@ import (
 	"wechat-api/ent/wxcard"
 	"wechat-api/ent/wxcarduser"
 	"wechat-api/ent/wxcardvisit"
+	"wechat-api/ent/xunji"
+	"wechat-api/ent/xunjiservice"
 )
 
 // The init function reads all schema descriptors with runtime code
@@ -698,32 +700,36 @@ func init() {
 	creditusageDescUserID := creditusageFields[0].Descriptor()
 	// creditusage.UserIDValidator is a validator for the "user_id" field. It is called by the builders before save.
 	creditusage.UserIDValidator = creditusageDescUserID.Validators[0].(func(string) error)
+	// creditusageDescPayMethod is the schema descriptor for pay_method field.
+	creditusageDescPayMethod := creditusageFields[5].Descriptor()
+	// creditusage.DefaultPayMethod holds the default value on creation for the pay_method field.
+	creditusage.DefaultPayMethod = creditusageDescPayMethod.Default.(int)
 	// creditusageDescStatus is the schema descriptor for status field.
-	creditusageDescStatus := creditusageFields[2].Descriptor()
+	creditusageDescStatus := creditusageFields[6].Descriptor()
 	// creditusage.DefaultStatus holds the default value on creation for the status field.
 	creditusage.DefaultStatus = creditusageDescStatus.Default.(int)
 	// creditusage.StatusValidator is a validator for the "status" field. It is called by the builders before save.
 	creditusage.StatusValidator = creditusageDescStatus.Validators[0].(func(int) error)
 	// creditusageDescNtype is the schema descriptor for ntype field.
-	creditusageDescNtype := creditusageFields[3].Descriptor()
+	creditusageDescNtype := creditusageFields[7].Descriptor()
 	// creditusage.DefaultNtype holds the default value on creation for the ntype field.
 	creditusage.DefaultNtype = creditusageDescNtype.Default.(int)
 	// creditusageDescTable is the schema descriptor for table field.
-	creditusageDescTable := creditusageFields[4].Descriptor()
+	creditusageDescTable := creditusageFields[8].Descriptor()
 	// creditusage.DefaultTable holds the default value on creation for the table field.
 	creditusage.DefaultTable = creditusageDescTable.Default.(string)
 	// creditusageDescNid is the schema descriptor for nid field.
-	creditusageDescNid := creditusageFields[6].Descriptor()
+	creditusageDescNid := creditusageFields[10].Descriptor()
 	// creditusage.DefaultNid holds the default value on creation for the nid field.
 	creditusage.DefaultNid = creditusageDescNid.Default.(uint64)
 	// creditusageDescReason is the schema descriptor for reason field.
-	creditusageDescReason := creditusageFields[7].Descriptor()
+	creditusageDescReason := creditusageFields[11].Descriptor()
 	// creditusage.DefaultReason holds the default value on creation for the reason field.
 	creditusage.DefaultReason = creditusageDescReason.Default.(string)
 	// creditusage.ReasonValidator is a validator for the "reason" field. It is called by the builders before save.
 	creditusage.ReasonValidator = creditusageDescReason.Validators[0].(func(string) error)
 	// creditusageDescOperator is the schema descriptor for operator field.
-	creditusageDescOperator := creditusageFields[8].Descriptor()
+	creditusageDescOperator := creditusageFields[12].Descriptor()
 	// creditusage.DefaultOperator holds the default value on creation for the operator field.
 	creditusage.DefaultOperator = creditusageDescOperator.Default.(string)
 	// creditusage.OperatorValidator is a validator for the "operator" field. It is called by the builders before save.
@@ -1430,6 +1436,10 @@ func init() {
 	usagedetailDescOrganizationID := usagedetailFields[11].Descriptor()
 	// usagedetail.DefaultOrganizationID holds the default value on creation for the organization_id field.
 	usagedetail.DefaultOrganizationID = usagedetailDescOrganizationID.Default.(uint64)
+	// usagedetailDescModel is the schema descriptor for model field.
+	usagedetailDescModel := usagedetailFields[12].Descriptor()
+	// usagedetail.DefaultModel holds the default value on creation for the model field.
+	usagedetail.DefaultModel = usagedetailDescModel.Default.(string)
 	usagestatisticdayMixin := schema.UsageStatisticDay{}.Mixin()
 	usagestatisticdayMixinHooks2 := usagestatisticdayMixin[2].Hooks()
 	usagestatisticday.Hooks[0] = usagestatisticdayMixinHooks2[0]
@@ -1455,6 +1465,10 @@ func init() {
 	usagestatisticdayDescStatus := usagestatisticdayMixinFields1[0].Descriptor()
 	// usagestatisticday.DefaultStatus holds the default value on creation for the status field.
 	usagestatisticday.DefaultStatus = usagestatisticdayDescStatus.Default.(uint8)
+	// usagestatisticdayDescConsumeCoin is the schema descriptor for consume_coin field.
+	usagestatisticdayDescConsumeCoin := usagestatisticdayFields[13].Descriptor()
+	// usagestatisticday.DefaultConsumeCoin holds the default value on creation for the consume_coin field.
+	usagestatisticday.DefaultConsumeCoin = usagestatisticdayDescConsumeCoin.Default.(float64)
 	usagestatistichourMixin := schema.UsageStatisticHour{}.Mixin()
 	usagestatistichourMixinHooks2 := usagestatistichourMixin[2].Hooks()
 	usagestatistichour.Hooks[0] = usagestatistichourMixinHooks2[0]
@@ -1480,6 +1494,10 @@ func init() {
 	usagestatistichourDescStatus := usagestatistichourMixinFields1[0].Descriptor()
 	// usagestatistichour.DefaultStatus holds the default value on creation for the status field.
 	usagestatistichour.DefaultStatus = usagestatistichourDescStatus.Default.(uint8)
+	// usagestatistichourDescConsumeCoin is the schema descriptor for consume_coin field.
+	usagestatistichourDescConsumeCoin := usagestatistichourFields[13].Descriptor()
+	// usagestatistichour.DefaultConsumeCoin holds the default value on creation for the consume_coin field.
+	usagestatistichour.DefaultConsumeCoin = usagestatistichourDescConsumeCoin.Default.(float64)
 	usagestatisticmonthMixin := schema.UsageStatisticMonth{}.Mixin()
 	usagestatisticmonthMixinHooks2 := usagestatisticmonthMixin[2].Hooks()
 	usagestatisticmonth.Hooks[0] = usagestatisticmonthMixinHooks2[0]
@@ -1505,6 +1523,10 @@ func init() {
 	usagestatisticmonthDescStatus := usagestatisticmonthMixinFields1[0].Descriptor()
 	// usagestatisticmonth.DefaultStatus holds the default value on creation for the status field.
 	usagestatisticmonth.DefaultStatus = usagestatisticmonthDescStatus.Default.(uint8)
+	// usagestatisticmonthDescConsumeCoin is the schema descriptor for consume_coin field.
+	usagestatisticmonthDescConsumeCoin := usagestatisticmonthFields[13].Descriptor()
+	// usagestatisticmonth.DefaultConsumeCoin holds the default value on creation for the consume_coin field.
+	usagestatisticmonth.DefaultConsumeCoin = usagestatisticmonthDescConsumeCoin.Default.(float64)
 	usagetotalMixin := schema.UsageTotal{}.Mixin()
 	usagetotalMixinFields0 := usagetotalMixin[0].Fields()
 	_ = usagetotalMixinFields0
@@ -2019,6 +2041,76 @@ func init() {
 	wxcardvisitDescBotType := wxcardvisitFields[2].Descriptor()
 	// wxcardvisit.DefaultBotType holds the default value on creation for the bot_type field.
 	wxcardvisit.DefaultBotType = wxcardvisitDescBotType.Default.(uint8)
+	xunjiMixin := schema.Xunji{}.Mixin()
+	xunjiMixinHooks2 := xunjiMixin[2].Hooks()
+	xunji.Hooks[0] = xunjiMixinHooks2[0]
+	xunjiMixinInters2 := xunjiMixin[2].Interceptors()
+	xunji.Interceptors[0] = xunjiMixinInters2[0]
+	xunjiMixinFields0 := xunjiMixin[0].Fields()
+	_ = xunjiMixinFields0
+	xunjiMixinFields1 := xunjiMixin[1].Fields()
+	_ = xunjiMixinFields1
+	xunjiFields := schema.Xunji{}.Fields()
+	_ = xunjiFields
+	// xunjiDescCreatedAt is the schema descriptor for created_at field.
+	xunjiDescCreatedAt := xunjiMixinFields0[1].Descriptor()
+	// xunji.DefaultCreatedAt holds the default value on creation for the created_at field.
+	xunji.DefaultCreatedAt = xunjiDescCreatedAt.Default.(func() time.Time)
+	// xunjiDescUpdatedAt is the schema descriptor for updated_at field.
+	xunjiDescUpdatedAt := xunjiMixinFields0[2].Descriptor()
+	// xunji.DefaultUpdatedAt holds the default value on creation for the updated_at field.
+	xunji.DefaultUpdatedAt = xunjiDescUpdatedAt.Default.(func() time.Time)
+	// xunji.UpdateDefaultUpdatedAt holds the default value on update for the updated_at field.
+	xunji.UpdateDefaultUpdatedAt = xunjiDescUpdatedAt.UpdateDefault.(func() time.Time)
+	// xunjiDescStatus is the schema descriptor for status field.
+	xunjiDescStatus := xunjiMixinFields1[0].Descriptor()
+	// xunji.DefaultStatus holds the default value on creation for the status field.
+	xunji.DefaultStatus = xunjiDescStatus.Default.(uint8)
+	// xunjiDescOrganizationID is the schema descriptor for organization_id field.
+	xunjiDescOrganizationID := xunjiFields[4].Descriptor()
+	// xunji.OrganizationIDValidator is a validator for the "organization_id" field. It is called by the builders before save.
+	xunji.OrganizationIDValidator = xunjiDescOrganizationID.Validators[0].(func(uint64) error)
+	xunjiserviceMixin := schema.XunjiService{}.Mixin()
+	xunjiserviceMixinHooks2 := xunjiserviceMixin[2].Hooks()
+	xunjiservice.Hooks[0] = xunjiserviceMixinHooks2[0]
+	xunjiserviceMixinInters2 := xunjiserviceMixin[2].Interceptors()
+	xunjiservice.Interceptors[0] = xunjiserviceMixinInters2[0]
+	xunjiserviceMixinFields0 := xunjiserviceMixin[0].Fields()
+	_ = xunjiserviceMixinFields0
+	xunjiserviceMixinFields1 := xunjiserviceMixin[1].Fields()
+	_ = xunjiserviceMixinFields1
+	xunjiserviceFields := schema.XunjiService{}.Fields()
+	_ = xunjiserviceFields
+	// xunjiserviceDescCreatedAt is the schema descriptor for created_at field.
+	xunjiserviceDescCreatedAt := xunjiserviceMixinFields0[1].Descriptor()
+	// xunjiservice.DefaultCreatedAt holds the default value on creation for the created_at field.
+	xunjiservice.DefaultCreatedAt = xunjiserviceDescCreatedAt.Default.(func() time.Time)
+	// xunjiserviceDescUpdatedAt is the schema descriptor for updated_at field.
+	xunjiserviceDescUpdatedAt := xunjiserviceMixinFields0[2].Descriptor()
+	// xunjiservice.DefaultUpdatedAt holds the default value on creation for the updated_at field.
+	xunjiservice.DefaultUpdatedAt = xunjiserviceDescUpdatedAt.Default.(func() time.Time)
+	// xunjiservice.UpdateDefaultUpdatedAt holds the default value on update for the updated_at field.
+	xunjiservice.UpdateDefaultUpdatedAt = xunjiserviceDescUpdatedAt.UpdateDefault.(func() time.Time)
+	// xunjiserviceDescStatus is the schema descriptor for status field.
+	xunjiserviceDescStatus := xunjiserviceMixinFields1[0].Descriptor()
+	// xunjiservice.DefaultStatus holds the default value on creation for the status field.
+	xunjiservice.DefaultStatus = xunjiserviceDescStatus.Default.(uint8)
+	// xunjiserviceDescAgentID is the schema descriptor for agent_id field.
+	xunjiserviceDescAgentID := xunjiserviceFields[1].Descriptor()
+	// xunjiservice.DefaultAgentID holds the default value on creation for the agent_id field.
+	xunjiservice.DefaultAgentID = xunjiserviceDescAgentID.Default.(uint64)
+	// xunjiserviceDescOrganizationID is the schema descriptor for organization_id field.
+	xunjiserviceDescOrganizationID := xunjiserviceFields[2].Descriptor()
+	// xunjiservice.OrganizationIDValidator is a validator for the "organization_id" field. It is called by the builders before save.
+	xunjiservice.OrganizationIDValidator = xunjiserviceDescOrganizationID.Validators[0].(func(uint64) error)
+	// xunjiserviceDescAPIBase is the schema descriptor for api_base field.
+	xunjiserviceDescAPIBase := xunjiserviceFields[4].Descriptor()
+	// xunjiservice.DefaultAPIBase holds the default value on creation for the api_base field.
+	xunjiservice.DefaultAPIBase = xunjiserviceDescAPIBase.Default.(string)
+	// xunjiserviceDescAPIKey is the schema descriptor for api_key field.
+	xunjiserviceDescAPIKey := xunjiserviceFields[5].Descriptor()
+	// xunjiservice.DefaultAPIKey holds the default value on creation for the api_key field.
+	xunjiservice.DefaultAPIKey = xunjiserviceDescAPIKey.Default.(string)
 }
 
 const (

+ 1 - 0
ent/schema/agent.go

@@ -45,6 +45,7 @@ func (Agent) Edges() []ent.Edge {
 		edge.To("wx_agent", Wx.Type),
 		edge.To("token_agent", Token.Type),
 		edge.To("wa_agent", Whatsapp.Type),
+		edge.To("xjs_agent", XunjiService.Type),
 		edge.To("key_agent", ApiKey.Type),
 	}
 }

+ 1 - 1
ent/schema/credit_balance.go

@@ -18,7 +18,7 @@ type CreditBalance struct {
 func (CreditBalance) Fields() []ent.Field {
 	return []ent.Field{
 		field.String("user_id").Optional().Comment("user_id | 用户ID"),
-		field.Float32("balance").Comment("role | 角色设定"),
+		field.Float("balance").Comment("balance | 积分余额"),
 		field.Int("status").Optional().Range(1, 2).Default(1).Comment("status | 状态 1-正常 2-禁用"),
 		field.Uint64("organization_id").Optional().Comment("organization_id | 租户ID"),
 	}

+ 5 - 1
ent/schema/credit_usage.go

@@ -18,7 +18,11 @@ type CreditUsage struct {
 func (CreditUsage) Fields() []ent.Field {
 	return []ent.Field{
 		field.String("user_id").Optional().MaxLen(255).Comment("user_id | 用户ID"),
-		field.Float32("number").Comment("number | 积分改变量"),
+		field.Float("number").Comment("number | 积分改变量"),
+		field.Float("pay_number").Optional().Comment("pay_number | 充值金额"),
+		field.Float("before_number").Optional().Comment("before_number | 变动前金额"),
+		field.Float("after_number").Optional().Comment("after_number | 变动后金额"),
+		field.Int("pay_method").Optional().Default(1).Comment("pay_method | 充值方式"),
 		field.Int("status").Optional().Range(1, 2).Default(1).Comment("status | 状态 1-正常 2-禁用"),
 		field.Int("ntype").Default(1).Comment("ntype | 积分变化类型:1-消耗 2-增加"),
 		field.String("table").Default("").Comment("table | 积分变化表名"),

+ 4 - 0
ent/schema/usage_detail.go

@@ -52,6 +52,10 @@ func (UsageDetail) Fields() []ent.Field {
 		field.Uint64("organization_id").Optional().Default(1).
 			Comment("机构 ID").
 			Annotations(entsql.WithComments(true)),
+		field.String("model").Optional().Default("GPT-4o mini").
+			Comment("模型").
+			Annotations(entsql.WithComments(true)),
+		field.Float("credits").Optional().Comment("coins | 积分消耗数"),
 	}
 }
 

+ 1 - 0
ent/schema/usage_statistic_day.go

@@ -33,6 +33,7 @@ func (UsageStatisticDay) Fields() []ent.Field {
 		field.JSON("label_dist", []custom_types.LabelDist{}).
 			Annotations(entsql.WithComments(true)).
 			Comment("标签分布"),
+		field.Float("consume_coin").Optional().Default(0).Comment("消耗积分"),
 	}
 }
 

+ 1 - 0
ent/schema/usage_statistic_hour.go

@@ -33,6 +33,7 @@ func (UsageStatisticHour) Fields() []ent.Field {
 		field.JSON("label_dist", []custom_types.LabelDist{}).
 			Annotations(entsql.WithComments(true)).
 			Comment("标签分布"),
+		field.Float("consume_coin").Optional().Default(0).Comment("消耗积分"),
 	}
 }
 

+ 1 - 0
ent/schema/usage_statistic_month.go

@@ -33,6 +33,7 @@ func (UsageStatisticMonth) Fields() []ent.Field {
 		field.JSON("label_dist", []custom_types.LabelDist{}).
 			Annotations(entsql.WithComments(true)).
 			Comment("标签分布"),
+		field.Float("consume_coin").Optional().Default(0).Comment("消耗积分"),
 	}
 }
 

+ 51 - 0
ent/schema/xunji.go

@@ -0,0 +1,51 @@
+package schema
+
+import (
+	"wechat-api/ent/schema/localmixin"
+
+	"entgo.io/ent"
+	"entgo.io/ent/dialect/entsql"
+	"entgo.io/ent/schema"
+	"entgo.io/ent/schema/field"
+	"entgo.io/ent/schema/index"
+	"github.com/suyuan32/simple-admin-common/orm/ent/mixins"
+)
+
+type Xunji struct {
+	ent.Schema
+}
+
+func (Xunji) Fields() []ent.Field {
+	return []ent.Field{
+		field.String("app_key").Optional().Comment("AppKey"),
+		field.String("app_secret").Optional().Comment("AppSecret"),
+		field.String("token").Optional().Comment("Token"),
+		field.String("encoding_key").Optional().Comment("加密key"),
+		field.Uint64("organization_id").Positive().Comment("organization_id | 租户ID"),
+	}
+}
+
+func (Xunji) Mixin() []ent.Mixin {
+	return []ent.Mixin{
+		mixins.IDMixin{},
+		mixins.StatusMixin{},
+		localmixin.SoftDeleteMixin{},
+	}
+}
+
+func (Xunji) Indexes() []ent.Index {
+	return []ent.Index{
+		index.Fields("app_key", "token"),
+	}
+}
+
+func (Xunji) Edges() []ent.Edge {
+	return []ent.Edge{}
+}
+
+func (Xunji) Annotations() []schema.Annotation {
+	return []schema.Annotation{
+		entsql.WithComments(true),
+		entsql.Annotation{Table: "xunji"},
+	}
+}

+ 60 - 0
ent/schema/xunji_service.go

@@ -0,0 +1,60 @@
+package schema
+
+import (
+	"entgo.io/ent/schema/edge"
+	"wechat-api/ent/schema/localmixin"
+
+	"entgo.io/ent"
+	"entgo.io/ent/dialect/entsql"
+	"entgo.io/ent/schema"
+	"entgo.io/ent/schema/field"
+	"entgo.io/ent/schema/index"
+	"github.com/suyuan32/simple-admin-common/orm/ent/mixins"
+)
+
+type XunjiService struct {
+	ent.Schema
+}
+
+func (XunjiService) Fields() []ent.Field {
+	return []ent.Field{
+		field.Uint64("xunji_id").Comment("Xunji表ID"),
+		field.Uint64("agent_id").Default(0).Comment("智能体ID"),
+		field.Uint64("organization_id").Positive().Comment("organization_id | 租户ID"),
+		field.String("wxid").Comment("微信ID"),
+		field.String("api_base").Optional().Default("").Comment("大模型服务地址"),
+		field.String("api_key").Optional().Default("").Comment("大模型服务密钥"),
+	}
+}
+
+func (XunjiService) Mixin() []ent.Mixin {
+	return []ent.Mixin{
+		mixins.IDMixin{},
+		mixins.StatusMixin{},
+		localmixin.SoftDeleteMixin{},
+	}
+}
+
+func (XunjiService) Indexes() []ent.Index {
+	return []ent.Index{
+		index.Fields("xunji_id"),
+		index.Fields("wxid"),
+	}
+}
+
+func (XunjiService) Edges() []ent.Edge {
+	return []ent.Edge{
+		edge.From("agent", Agent.Type).
+			Ref("xjs_agent").
+			Unique().
+			Field("agent_id").
+			Required(),
+	}
+}
+
+func (XunjiService) Annotations() []schema.Annotation {
+	return []schema.Annotation{
+		entsql.WithComments(true),
+		entsql.Annotation{Table: "xunji_service"},
+	}
+}

+ 630 - 6
ent/set_not_nil.go

@@ -3608,7 +3608,7 @@ func (cb *CreditBalanceCreate) SetNotNilUserID(value *string) *CreditBalanceCrea
 }
 
 // set field if value's pointer is not nil.
-func (cb *CreditBalanceUpdate) SetNotNilBalance(value *float32) *CreditBalanceUpdate {
+func (cb *CreditBalanceUpdate) SetNotNilBalance(value *float64) *CreditBalanceUpdate {
 	if value != nil {
 		return cb.SetBalance(*value)
 	}
@@ -3616,7 +3616,7 @@ func (cb *CreditBalanceUpdate) SetNotNilBalance(value *float32) *CreditBalanceUp
 }
 
 // set field if value's pointer is not nil.
-func (cb *CreditBalanceUpdateOne) SetNotNilBalance(value *float32) *CreditBalanceUpdateOne {
+func (cb *CreditBalanceUpdateOne) SetNotNilBalance(value *float64) *CreditBalanceUpdateOne {
 	if value != nil {
 		return cb.SetBalance(*value)
 	}
@@ -3624,7 +3624,7 @@ func (cb *CreditBalanceUpdateOne) SetNotNilBalance(value *float32) *CreditBalanc
 }
 
 // set field if value's pointer is not nil.
-func (cb *CreditBalanceCreate) SetNotNilBalance(value *float32) *CreditBalanceCreate {
+func (cb *CreditBalanceCreate) SetNotNilBalance(value *float64) *CreditBalanceCreate {
 	if value != nil {
 		return cb.SetBalance(*value)
 	}
@@ -3752,7 +3752,7 @@ func (cu *CreditUsageCreate) SetNotNilUserID(value *string) *CreditUsageCreate {
 }
 
 // set field if value's pointer is not nil.
-func (cu *CreditUsageUpdate) SetNotNilNumber(value *float32) *CreditUsageUpdate {
+func (cu *CreditUsageUpdate) SetNotNilNumber(value *float64) *CreditUsageUpdate {
 	if value != nil {
 		return cu.SetNumber(*value)
 	}
@@ -3760,7 +3760,7 @@ func (cu *CreditUsageUpdate) SetNotNilNumber(value *float32) *CreditUsageUpdate
 }
 
 // set field if value's pointer is not nil.
-func (cu *CreditUsageUpdateOne) SetNotNilNumber(value *float32) *CreditUsageUpdateOne {
+func (cu *CreditUsageUpdateOne) SetNotNilNumber(value *float64) *CreditUsageUpdateOne {
 	if value != nil {
 		return cu.SetNumber(*value)
 	}
@@ -3768,7 +3768,7 @@ func (cu *CreditUsageUpdateOne) SetNotNilNumber(value *float32) *CreditUsageUpda
 }
 
 // set field if value's pointer is not nil.
-func (cu *CreditUsageCreate) SetNotNilNumber(value *float32) *CreditUsageCreate {
+func (cu *CreditUsageCreate) SetNotNilNumber(value *float64) *CreditUsageCreate {
 	if value != nil {
 		return cu.SetNumber(*value)
 	}
@@ -3776,6 +3776,102 @@ func (cu *CreditUsageCreate) SetNotNilNumber(value *float32) *CreditUsageCreate
 }
 
 // set field if value's pointer is not nil.
+func (cu *CreditUsageUpdate) SetNotNilPayNumber(value *float64) *CreditUsageUpdate {
+	if value != nil {
+		return cu.SetPayNumber(*value)
+	}
+	return cu
+}
+
+// set field if value's pointer is not nil.
+func (cu *CreditUsageUpdateOne) SetNotNilPayNumber(value *float64) *CreditUsageUpdateOne {
+	if value != nil {
+		return cu.SetPayNumber(*value)
+	}
+	return cu
+}
+
+// set field if value's pointer is not nil.
+func (cu *CreditUsageCreate) SetNotNilPayNumber(value *float64) *CreditUsageCreate {
+	if value != nil {
+		return cu.SetPayNumber(*value)
+	}
+	return cu
+}
+
+// set field if value's pointer is not nil.
+func (cu *CreditUsageUpdate) SetNotNilBeforeNumber(value *float64) *CreditUsageUpdate {
+	if value != nil {
+		return cu.SetBeforeNumber(*value)
+	}
+	return cu
+}
+
+// set field if value's pointer is not nil.
+func (cu *CreditUsageUpdateOne) SetNotNilBeforeNumber(value *float64) *CreditUsageUpdateOne {
+	if value != nil {
+		return cu.SetBeforeNumber(*value)
+	}
+	return cu
+}
+
+// set field if value's pointer is not nil.
+func (cu *CreditUsageCreate) SetNotNilBeforeNumber(value *float64) *CreditUsageCreate {
+	if value != nil {
+		return cu.SetBeforeNumber(*value)
+	}
+	return cu
+}
+
+// set field if value's pointer is not nil.
+func (cu *CreditUsageUpdate) SetNotNilAfterNumber(value *float64) *CreditUsageUpdate {
+	if value != nil {
+		return cu.SetAfterNumber(*value)
+	}
+	return cu
+}
+
+// set field if value's pointer is not nil.
+func (cu *CreditUsageUpdateOne) SetNotNilAfterNumber(value *float64) *CreditUsageUpdateOne {
+	if value != nil {
+		return cu.SetAfterNumber(*value)
+	}
+	return cu
+}
+
+// set field if value's pointer is not nil.
+func (cu *CreditUsageCreate) SetNotNilAfterNumber(value *float64) *CreditUsageCreate {
+	if value != nil {
+		return cu.SetAfterNumber(*value)
+	}
+	return cu
+}
+
+// set field if value's pointer is not nil.
+func (cu *CreditUsageUpdate) SetNotNilPayMethod(value *int) *CreditUsageUpdate {
+	if value != nil {
+		return cu.SetPayMethod(*value)
+	}
+	return cu
+}
+
+// set field if value's pointer is not nil.
+func (cu *CreditUsageUpdateOne) SetNotNilPayMethod(value *int) *CreditUsageUpdateOne {
+	if value != nil {
+		return cu.SetPayMethod(*value)
+	}
+	return cu
+}
+
+// set field if value's pointer is not nil.
+func (cu *CreditUsageCreate) SetNotNilPayMethod(value *int) *CreditUsageCreate {
+	if value != nil {
+		return cu.SetPayMethod(*value)
+	}
+	return cu
+}
+
+// set field if value's pointer is not nil.
 func (cu *CreditUsageUpdate) SetNotNilStatus(value *int) *CreditUsageUpdate {
 	if value != nil {
 		return cu.SetStatus(*value)
@@ -7952,6 +8048,54 @@ func (ud *UsageDetailCreate) SetNotNilOrganizationID(value *uint64) *UsageDetail
 }
 
 // set field if value's pointer is not nil.
+func (ud *UsageDetailUpdate) SetNotNilModel(value *string) *UsageDetailUpdate {
+	if value != nil {
+		return ud.SetModel(*value)
+	}
+	return ud
+}
+
+// set field if value's pointer is not nil.
+func (ud *UsageDetailUpdateOne) SetNotNilModel(value *string) *UsageDetailUpdateOne {
+	if value != nil {
+		return ud.SetModel(*value)
+	}
+	return ud
+}
+
+// set field if value's pointer is not nil.
+func (ud *UsageDetailCreate) SetNotNilModel(value *string) *UsageDetailCreate {
+	if value != nil {
+		return ud.SetModel(*value)
+	}
+	return ud
+}
+
+// set field if value's pointer is not nil.
+func (ud *UsageDetailUpdate) SetNotNilCredits(value *float64) *UsageDetailUpdate {
+	if value != nil {
+		return ud.SetCredits(*value)
+	}
+	return ud
+}
+
+// set field if value's pointer is not nil.
+func (ud *UsageDetailUpdateOne) SetNotNilCredits(value *float64) *UsageDetailUpdateOne {
+	if value != nil {
+		return ud.SetCredits(*value)
+	}
+	return ud
+}
+
+// set field if value's pointer is not nil.
+func (ud *UsageDetailCreate) SetNotNilCredits(value *float64) *UsageDetailCreate {
+	if value != nil {
+		return ud.SetCredits(*value)
+	}
+	return ud
+}
+
+// set field if value's pointer is not nil.
 func (usd *UsageStatisticDayUpdate) SetNotNilUpdatedAt(value *time.Time) *UsageStatisticDayUpdate {
 	if value != nil {
 		return usd.SetUpdatedAt(*value)
@@ -8336,6 +8480,30 @@ func (usd *UsageStatisticDayCreate) SetNotNilLabelDist(value []custom_types.Labe
 }
 
 // set field if value's pointer is not nil.
+func (usd *UsageStatisticDayUpdate) SetNotNilConsumeCoin(value *float64) *UsageStatisticDayUpdate {
+	if value != nil {
+		return usd.SetConsumeCoin(*value)
+	}
+	return usd
+}
+
+// set field if value's pointer is not nil.
+func (usd *UsageStatisticDayUpdateOne) SetNotNilConsumeCoin(value *float64) *UsageStatisticDayUpdateOne {
+	if value != nil {
+		return usd.SetConsumeCoin(*value)
+	}
+	return usd
+}
+
+// set field if value's pointer is not nil.
+func (usd *UsageStatisticDayCreate) SetNotNilConsumeCoin(value *float64) *UsageStatisticDayCreate {
+	if value != nil {
+		return usd.SetConsumeCoin(*value)
+	}
+	return usd
+}
+
+// set field if value's pointer is not nil.
 func (ush *UsageStatisticHourUpdate) SetNotNilUpdatedAt(value *time.Time) *UsageStatisticHourUpdate {
 	if value != nil {
 		return ush.SetUpdatedAt(*value)
@@ -8720,6 +8888,30 @@ func (ush *UsageStatisticHourCreate) SetNotNilLabelDist(value []custom_types.Lab
 }
 
 // set field if value's pointer is not nil.
+func (ush *UsageStatisticHourUpdate) SetNotNilConsumeCoin(value *float64) *UsageStatisticHourUpdate {
+	if value != nil {
+		return ush.SetConsumeCoin(*value)
+	}
+	return ush
+}
+
+// set field if value's pointer is not nil.
+func (ush *UsageStatisticHourUpdateOne) SetNotNilConsumeCoin(value *float64) *UsageStatisticHourUpdateOne {
+	if value != nil {
+		return ush.SetConsumeCoin(*value)
+	}
+	return ush
+}
+
+// set field if value's pointer is not nil.
+func (ush *UsageStatisticHourCreate) SetNotNilConsumeCoin(value *float64) *UsageStatisticHourCreate {
+	if value != nil {
+		return ush.SetConsumeCoin(*value)
+	}
+	return ush
+}
+
+// set field if value's pointer is not nil.
 func (usm *UsageStatisticMonthUpdate) SetNotNilUpdatedAt(value *time.Time) *UsageStatisticMonthUpdate {
 	if value != nil {
 		return usm.SetUpdatedAt(*value)
@@ -9104,6 +9296,30 @@ func (usm *UsageStatisticMonthCreate) SetNotNilLabelDist(value []custom_types.La
 }
 
 // set field if value's pointer is not nil.
+func (usm *UsageStatisticMonthUpdate) SetNotNilConsumeCoin(value *float64) *UsageStatisticMonthUpdate {
+	if value != nil {
+		return usm.SetConsumeCoin(*value)
+	}
+	return usm
+}
+
+// set field if value's pointer is not nil.
+func (usm *UsageStatisticMonthUpdateOne) SetNotNilConsumeCoin(value *float64) *UsageStatisticMonthUpdateOne {
+	if value != nil {
+		return usm.SetConsumeCoin(*value)
+	}
+	return usm
+}
+
+// set field if value's pointer is not nil.
+func (usm *UsageStatisticMonthCreate) SetNotNilConsumeCoin(value *float64) *UsageStatisticMonthCreate {
+	if value != nil {
+		return usm.SetConsumeCoin(*value)
+	}
+	return usm
+}
+
+// set field if value's pointer is not nil.
 func (ut *UsageTotalUpdate) SetNotNilUpdatedAt(value *time.Time) *UsageTotalUpdate {
 	if value != nil {
 		return ut.SetUpdatedAt(*value)
@@ -11886,3 +12102,411 @@ func (wcv *WxCardVisitCreate) SetNotNilBotType(value *uint8) *WxCardVisitCreate
 	}
 	return wcv
 }
+
+// set field if value's pointer is not nil.
+func (x *XunjiUpdate) SetNotNilUpdatedAt(value *time.Time) *XunjiUpdate {
+	if value != nil {
+		return x.SetUpdatedAt(*value)
+	}
+	return x
+}
+
+// set field if value's pointer is not nil.
+func (x *XunjiUpdateOne) SetNotNilUpdatedAt(value *time.Time) *XunjiUpdateOne {
+	if value != nil {
+		return x.SetUpdatedAt(*value)
+	}
+	return x
+}
+
+// set field if value's pointer is not nil.
+func (x *XunjiCreate) SetNotNilUpdatedAt(value *time.Time) *XunjiCreate {
+	if value != nil {
+		return x.SetUpdatedAt(*value)
+	}
+	return x
+}
+
+// set field if value's pointer is not nil.
+func (x *XunjiUpdate) SetNotNilStatus(value *uint8) *XunjiUpdate {
+	if value != nil {
+		return x.SetStatus(*value)
+	}
+	return x
+}
+
+// set field if value's pointer is not nil.
+func (x *XunjiUpdateOne) SetNotNilStatus(value *uint8) *XunjiUpdateOne {
+	if value != nil {
+		return x.SetStatus(*value)
+	}
+	return x
+}
+
+// set field if value's pointer is not nil.
+func (x *XunjiCreate) SetNotNilStatus(value *uint8) *XunjiCreate {
+	if value != nil {
+		return x.SetStatus(*value)
+	}
+	return x
+}
+
+// set field if value's pointer is not nil.
+func (x *XunjiUpdate) SetNotNilDeletedAt(value *time.Time) *XunjiUpdate {
+	if value != nil {
+		return x.SetDeletedAt(*value)
+	}
+	return x
+}
+
+// set field if value's pointer is not nil.
+func (x *XunjiUpdateOne) SetNotNilDeletedAt(value *time.Time) *XunjiUpdateOne {
+	if value != nil {
+		return x.SetDeletedAt(*value)
+	}
+	return x
+}
+
+// set field if value's pointer is not nil.
+func (x *XunjiCreate) SetNotNilDeletedAt(value *time.Time) *XunjiCreate {
+	if value != nil {
+		return x.SetDeletedAt(*value)
+	}
+	return x
+}
+
+// set field if value's pointer is not nil.
+func (x *XunjiUpdate) SetNotNilAppKey(value *string) *XunjiUpdate {
+	if value != nil {
+		return x.SetAppKey(*value)
+	}
+	return x
+}
+
+// set field if value's pointer is not nil.
+func (x *XunjiUpdateOne) SetNotNilAppKey(value *string) *XunjiUpdateOne {
+	if value != nil {
+		return x.SetAppKey(*value)
+	}
+	return x
+}
+
+// set field if value's pointer is not nil.
+func (x *XunjiCreate) SetNotNilAppKey(value *string) *XunjiCreate {
+	if value != nil {
+		return x.SetAppKey(*value)
+	}
+	return x
+}
+
+// set field if value's pointer is not nil.
+func (x *XunjiUpdate) SetNotNilAppSecret(value *string) *XunjiUpdate {
+	if value != nil {
+		return x.SetAppSecret(*value)
+	}
+	return x
+}
+
+// set field if value's pointer is not nil.
+func (x *XunjiUpdateOne) SetNotNilAppSecret(value *string) *XunjiUpdateOne {
+	if value != nil {
+		return x.SetAppSecret(*value)
+	}
+	return x
+}
+
+// set field if value's pointer is not nil.
+func (x *XunjiCreate) SetNotNilAppSecret(value *string) *XunjiCreate {
+	if value != nil {
+		return x.SetAppSecret(*value)
+	}
+	return x
+}
+
+// set field if value's pointer is not nil.
+func (x *XunjiUpdate) SetNotNilToken(value *string) *XunjiUpdate {
+	if value != nil {
+		return x.SetToken(*value)
+	}
+	return x
+}
+
+// set field if value's pointer is not nil.
+func (x *XunjiUpdateOne) SetNotNilToken(value *string) *XunjiUpdateOne {
+	if value != nil {
+		return x.SetToken(*value)
+	}
+	return x
+}
+
+// set field if value's pointer is not nil.
+func (x *XunjiCreate) SetNotNilToken(value *string) *XunjiCreate {
+	if value != nil {
+		return x.SetToken(*value)
+	}
+	return x
+}
+
+// set field if value's pointer is not nil.
+func (x *XunjiUpdate) SetNotNilEncodingKey(value *string) *XunjiUpdate {
+	if value != nil {
+		return x.SetEncodingKey(*value)
+	}
+	return x
+}
+
+// set field if value's pointer is not nil.
+func (x *XunjiUpdateOne) SetNotNilEncodingKey(value *string) *XunjiUpdateOne {
+	if value != nil {
+		return x.SetEncodingKey(*value)
+	}
+	return x
+}
+
+// set field if value's pointer is not nil.
+func (x *XunjiCreate) SetNotNilEncodingKey(value *string) *XunjiCreate {
+	if value != nil {
+		return x.SetEncodingKey(*value)
+	}
+	return x
+}
+
+// set field if value's pointer is not nil.
+func (x *XunjiUpdate) SetNotNilOrganizationID(value *uint64) *XunjiUpdate {
+	if value != nil {
+		return x.SetOrganizationID(*value)
+	}
+	return x
+}
+
+// set field if value's pointer is not nil.
+func (x *XunjiUpdateOne) SetNotNilOrganizationID(value *uint64) *XunjiUpdateOne {
+	if value != nil {
+		return x.SetOrganizationID(*value)
+	}
+	return x
+}
+
+// set field if value's pointer is not nil.
+func (x *XunjiCreate) SetNotNilOrganizationID(value *uint64) *XunjiCreate {
+	if value != nil {
+		return x.SetOrganizationID(*value)
+	}
+	return x
+}
+
+// set field if value's pointer is not nil.
+func (xs *XunjiServiceUpdate) SetNotNilUpdatedAt(value *time.Time) *XunjiServiceUpdate {
+	if value != nil {
+		return xs.SetUpdatedAt(*value)
+	}
+	return xs
+}
+
+// set field if value's pointer is not nil.
+func (xs *XunjiServiceUpdateOne) SetNotNilUpdatedAt(value *time.Time) *XunjiServiceUpdateOne {
+	if value != nil {
+		return xs.SetUpdatedAt(*value)
+	}
+	return xs
+}
+
+// set field if value's pointer is not nil.
+func (xs *XunjiServiceCreate) SetNotNilUpdatedAt(value *time.Time) *XunjiServiceCreate {
+	if value != nil {
+		return xs.SetUpdatedAt(*value)
+	}
+	return xs
+}
+
+// set field if value's pointer is not nil.
+func (xs *XunjiServiceUpdate) SetNotNilStatus(value *uint8) *XunjiServiceUpdate {
+	if value != nil {
+		return xs.SetStatus(*value)
+	}
+	return xs
+}
+
+// set field if value's pointer is not nil.
+func (xs *XunjiServiceUpdateOne) SetNotNilStatus(value *uint8) *XunjiServiceUpdateOne {
+	if value != nil {
+		return xs.SetStatus(*value)
+	}
+	return xs
+}
+
+// set field if value's pointer is not nil.
+func (xs *XunjiServiceCreate) SetNotNilStatus(value *uint8) *XunjiServiceCreate {
+	if value != nil {
+		return xs.SetStatus(*value)
+	}
+	return xs
+}
+
+// set field if value's pointer is not nil.
+func (xs *XunjiServiceUpdate) SetNotNilDeletedAt(value *time.Time) *XunjiServiceUpdate {
+	if value != nil {
+		return xs.SetDeletedAt(*value)
+	}
+	return xs
+}
+
+// set field if value's pointer is not nil.
+func (xs *XunjiServiceUpdateOne) SetNotNilDeletedAt(value *time.Time) *XunjiServiceUpdateOne {
+	if value != nil {
+		return xs.SetDeletedAt(*value)
+	}
+	return xs
+}
+
+// set field if value's pointer is not nil.
+func (xs *XunjiServiceCreate) SetNotNilDeletedAt(value *time.Time) *XunjiServiceCreate {
+	if value != nil {
+		return xs.SetDeletedAt(*value)
+	}
+	return xs
+}
+
+// set field if value's pointer is not nil.
+func (xs *XunjiServiceUpdate) SetNotNilXunjiID(value *uint64) *XunjiServiceUpdate {
+	if value != nil {
+		return xs.SetXunjiID(*value)
+	}
+	return xs
+}
+
+// set field if value's pointer is not nil.
+func (xs *XunjiServiceUpdateOne) SetNotNilXunjiID(value *uint64) *XunjiServiceUpdateOne {
+	if value != nil {
+		return xs.SetXunjiID(*value)
+	}
+	return xs
+}
+
+// set field if value's pointer is not nil.
+func (xs *XunjiServiceCreate) SetNotNilXunjiID(value *uint64) *XunjiServiceCreate {
+	if value != nil {
+		return xs.SetXunjiID(*value)
+	}
+	return xs
+}
+
+// set field if value's pointer is not nil.
+func (xs *XunjiServiceUpdate) SetNotNilAgentID(value *uint64) *XunjiServiceUpdate {
+	if value != nil {
+		return xs.SetAgentID(*value)
+	}
+	return xs
+}
+
+// set field if value's pointer is not nil.
+func (xs *XunjiServiceUpdateOne) SetNotNilAgentID(value *uint64) *XunjiServiceUpdateOne {
+	if value != nil {
+		return xs.SetAgentID(*value)
+	}
+	return xs
+}
+
+// set field if value's pointer is not nil.
+func (xs *XunjiServiceCreate) SetNotNilAgentID(value *uint64) *XunjiServiceCreate {
+	if value != nil {
+		return xs.SetAgentID(*value)
+	}
+	return xs
+}
+
+// set field if value's pointer is not nil.
+func (xs *XunjiServiceUpdate) SetNotNilOrganizationID(value *uint64) *XunjiServiceUpdate {
+	if value != nil {
+		return xs.SetOrganizationID(*value)
+	}
+	return xs
+}
+
+// set field if value's pointer is not nil.
+func (xs *XunjiServiceUpdateOne) SetNotNilOrganizationID(value *uint64) *XunjiServiceUpdateOne {
+	if value != nil {
+		return xs.SetOrganizationID(*value)
+	}
+	return xs
+}
+
+// set field if value's pointer is not nil.
+func (xs *XunjiServiceCreate) SetNotNilOrganizationID(value *uint64) *XunjiServiceCreate {
+	if value != nil {
+		return xs.SetOrganizationID(*value)
+	}
+	return xs
+}
+
+// set field if value's pointer is not nil.
+func (xs *XunjiServiceUpdate) SetNotNilWxid(value *string) *XunjiServiceUpdate {
+	if value != nil {
+		return xs.SetWxid(*value)
+	}
+	return xs
+}
+
+// set field if value's pointer is not nil.
+func (xs *XunjiServiceUpdateOne) SetNotNilWxid(value *string) *XunjiServiceUpdateOne {
+	if value != nil {
+		return xs.SetWxid(*value)
+	}
+	return xs
+}
+
+// set field if value's pointer is not nil.
+func (xs *XunjiServiceCreate) SetNotNilWxid(value *string) *XunjiServiceCreate {
+	if value != nil {
+		return xs.SetWxid(*value)
+	}
+	return xs
+}
+
+// set field if value's pointer is not nil.
+func (xs *XunjiServiceUpdate) SetNotNilAPIBase(value *string) *XunjiServiceUpdate {
+	if value != nil {
+		return xs.SetAPIBase(*value)
+	}
+	return xs
+}
+
+// set field if value's pointer is not nil.
+func (xs *XunjiServiceUpdateOne) SetNotNilAPIBase(value *string) *XunjiServiceUpdateOne {
+	if value != nil {
+		return xs.SetAPIBase(*value)
+	}
+	return xs
+}
+
+// set field if value's pointer is not nil.
+func (xs *XunjiServiceCreate) SetNotNilAPIBase(value *string) *XunjiServiceCreate {
+	if value != nil {
+		return xs.SetAPIBase(*value)
+	}
+	return xs
+}
+
+// set field if value's pointer is not nil.
+func (xs *XunjiServiceUpdate) SetNotNilAPIKey(value *string) *XunjiServiceUpdate {
+	if value != nil {
+		return xs.SetAPIKey(*value)
+	}
+	return xs
+}
+
+// set field if value's pointer is not nil.
+func (xs *XunjiServiceUpdateOne) SetNotNilAPIKey(value *string) *XunjiServiceUpdateOne {
+	if value != nil {
+		return xs.SetAPIKey(*value)
+	}
+	return xs
+}
+
+// set field if value's pointer is not nil.
+func (xs *XunjiServiceCreate) SetNotNilAPIKey(value *string) *XunjiServiceCreate {
+	if value != nil {
+		return xs.SetAPIKey(*value)
+	}
+	return xs
+}

+ 6 - 0
ent/tx.go

@@ -104,6 +104,10 @@ type Tx struct {
 	WxCardUser *WxCardUserClient
 	// WxCardVisit is the client for interacting with the WxCardVisit builders.
 	WxCardVisit *WxCardVisitClient
+	// Xunji is the client for interacting with the Xunji builders.
+	Xunji *XunjiClient
+	// XunjiService is the client for interacting with the XunjiService builders.
+	XunjiService *XunjiServiceClient
 
 	// lazily loaded.
 	client     *Client
@@ -280,6 +284,8 @@ func (tx *Tx) init() {
 	tx.WxCard = NewWxCardClient(tx.config)
 	tx.WxCardUser = NewWxCardUserClient(tx.config)
 	tx.WxCardVisit = NewWxCardVisitClient(tx.config)
+	tx.Xunji = NewXunjiClient(tx.config)
+	tx.XunjiService = NewXunjiServiceClient(tx.config)
 }
 
 // txDriver wraps the given dialect.Tx with a nop dialect.Driver implementation.

+ 26 - 2
ent/usagedetail.go

@@ -49,7 +49,11 @@ type UsageDetail struct {
 	CompletionTokens uint64 `json:"completion_tokens,omitempty"`
 	// 机构 ID
 	OrganizationID uint64 `json:"organization_id,omitempty"`
-	selectValues   sql.SelectValues
+	// 模型
+	Model string `json:"model,omitempty"`
+	// coins | 积分消耗数
+	Credits      float64 `json:"credits,omitempty"`
+	selectValues sql.SelectValues
 }
 
 // scanValues returns the types for scanning values from sql.Rows.
@@ -59,9 +63,11 @@ func (*UsageDetail) scanValues(columns []string) ([]any, error) {
 		switch columns[i] {
 		case usagedetail.FieldOriginalData:
 			values[i] = new([]byte)
+		case usagedetail.FieldCredits:
+			values[i] = new(sql.NullFloat64)
 		case usagedetail.FieldID, usagedetail.FieldStatus, usagedetail.FieldType, usagedetail.FieldApp, usagedetail.FieldSessionID, usagedetail.FieldTotalTokens, usagedetail.FieldPromptTokens, usagedetail.FieldCompletionTokens, usagedetail.FieldOrganizationID:
 			values[i] = new(sql.NullInt64)
-		case usagedetail.FieldBotID, usagedetail.FieldReceiverID, usagedetail.FieldRequest, usagedetail.FieldResponse:
+		case usagedetail.FieldBotID, usagedetail.FieldReceiverID, usagedetail.FieldRequest, usagedetail.FieldResponse, usagedetail.FieldModel:
 			values[i] = new(sql.NullString)
 		case usagedetail.FieldCreatedAt, usagedetail.FieldUpdatedAt:
 			values[i] = new(sql.NullTime)
@@ -178,6 +184,18 @@ func (ud *UsageDetail) assignValues(columns []string, values []any) error {
 			} else if value.Valid {
 				ud.OrganizationID = uint64(value.Int64)
 			}
+		case usagedetail.FieldModel:
+			if value, ok := values[i].(*sql.NullString); !ok {
+				return fmt.Errorf("unexpected type %T for field model", values[i])
+			} else if value.Valid {
+				ud.Model = value.String
+			}
+		case usagedetail.FieldCredits:
+			if value, ok := values[i].(*sql.NullFloat64); !ok {
+				return fmt.Errorf("unexpected type %T for field credits", values[i])
+			} else if value.Valid {
+				ud.Credits = value.Float64
+			}
 		default:
 			ud.selectValues.Set(columns[i], values[i])
 		}
@@ -258,6 +276,12 @@ func (ud *UsageDetail) String() string {
 	builder.WriteString(", ")
 	builder.WriteString("organization_id=")
 	builder.WriteString(fmt.Sprintf("%v", ud.OrganizationID))
+	builder.WriteString(", ")
+	builder.WriteString("model=")
+	builder.WriteString(ud.Model)
+	builder.WriteString(", ")
+	builder.WriteString("credits=")
+	builder.WriteString(fmt.Sprintf("%v", ud.Credits))
 	builder.WriteByte(')')
 	return builder.String()
 }

+ 18 - 0
ent/usagedetail/usagedetail.go

@@ -43,6 +43,10 @@ const (
 	FieldCompletionTokens = "completion_tokens"
 	// FieldOrganizationID holds the string denoting the organization_id field in the database.
 	FieldOrganizationID = "organization_id"
+	// FieldModel holds the string denoting the model field in the database.
+	FieldModel = "model"
+	// FieldCredits holds the string denoting the credits field in the database.
+	FieldCredits = "credits"
 	// Table holds the table name of the usagedetail in the database.
 	Table = "usage_detail"
 )
@@ -65,6 +69,8 @@ var Columns = []string{
 	FieldPromptTokens,
 	FieldCompletionTokens,
 	FieldOrganizationID,
+	FieldModel,
+	FieldCredits,
 }
 
 // ValidColumn reports if the column name is valid (part of the table columns).
@@ -108,6 +114,8 @@ var (
 	DefaultCompletionTokens uint64
 	// DefaultOrganizationID holds the default value on creation for the "organization_id" field.
 	DefaultOrganizationID uint64
+	// DefaultModel holds the default value on creation for the "model" field.
+	DefaultModel string
 )
 
 // OrderOption defines the ordering options for the UsageDetail queries.
@@ -187,3 +195,13 @@ func ByCompletionTokens(opts ...sql.OrderTermOption) OrderOption {
 func ByOrganizationID(opts ...sql.OrderTermOption) OrderOption {
 	return sql.OrderByField(FieldOrganizationID, opts...).ToFunc()
 }
+
+// ByModel orders the results by the model field.
+func ByModel(opts ...sql.OrderTermOption) OrderOption {
+	return sql.OrderByField(FieldModel, opts...).ToFunc()
+}
+
+// ByCredits orders the results by the credits field.
+func ByCredits(opts ...sql.OrderTermOption) OrderOption {
+	return sql.OrderByField(FieldCredits, opts...).ToFunc()
+}

+ 135 - 0
ent/usagedetail/where.go

@@ -124,6 +124,16 @@ func OrganizationID(v uint64) predicate.UsageDetail {
 	return predicate.UsageDetail(sql.FieldEQ(FieldOrganizationID, v))
 }
 
+// Model applies equality check predicate on the "model" field. It's identical to ModelEQ.
+func Model(v string) predicate.UsageDetail {
+	return predicate.UsageDetail(sql.FieldEQ(FieldModel, v))
+}
+
+// Credits applies equality check predicate on the "credits" field. It's identical to CreditsEQ.
+func Credits(v float64) predicate.UsageDetail {
+	return predicate.UsageDetail(sql.FieldEQ(FieldCredits, v))
+}
+
 // CreatedAtEQ applies the EQ predicate on the "created_at" field.
 func CreatedAtEQ(v time.Time) predicate.UsageDetail {
 	return predicate.UsageDetail(sql.FieldEQ(FieldCreatedAt, v))
@@ -864,6 +874,131 @@ func OrganizationIDNotNil() predicate.UsageDetail {
 	return predicate.UsageDetail(sql.FieldNotNull(FieldOrganizationID))
 }
 
+// ModelEQ applies the EQ predicate on the "model" field.
+func ModelEQ(v string) predicate.UsageDetail {
+	return predicate.UsageDetail(sql.FieldEQ(FieldModel, v))
+}
+
+// ModelNEQ applies the NEQ predicate on the "model" field.
+func ModelNEQ(v string) predicate.UsageDetail {
+	return predicate.UsageDetail(sql.FieldNEQ(FieldModel, v))
+}
+
+// ModelIn applies the In predicate on the "model" field.
+func ModelIn(vs ...string) predicate.UsageDetail {
+	return predicate.UsageDetail(sql.FieldIn(FieldModel, vs...))
+}
+
+// ModelNotIn applies the NotIn predicate on the "model" field.
+func ModelNotIn(vs ...string) predicate.UsageDetail {
+	return predicate.UsageDetail(sql.FieldNotIn(FieldModel, vs...))
+}
+
+// ModelGT applies the GT predicate on the "model" field.
+func ModelGT(v string) predicate.UsageDetail {
+	return predicate.UsageDetail(sql.FieldGT(FieldModel, v))
+}
+
+// ModelGTE applies the GTE predicate on the "model" field.
+func ModelGTE(v string) predicate.UsageDetail {
+	return predicate.UsageDetail(sql.FieldGTE(FieldModel, v))
+}
+
+// ModelLT applies the LT predicate on the "model" field.
+func ModelLT(v string) predicate.UsageDetail {
+	return predicate.UsageDetail(sql.FieldLT(FieldModel, v))
+}
+
+// ModelLTE applies the LTE predicate on the "model" field.
+func ModelLTE(v string) predicate.UsageDetail {
+	return predicate.UsageDetail(sql.FieldLTE(FieldModel, v))
+}
+
+// ModelContains applies the Contains predicate on the "model" field.
+func ModelContains(v string) predicate.UsageDetail {
+	return predicate.UsageDetail(sql.FieldContains(FieldModel, v))
+}
+
+// ModelHasPrefix applies the HasPrefix predicate on the "model" field.
+func ModelHasPrefix(v string) predicate.UsageDetail {
+	return predicate.UsageDetail(sql.FieldHasPrefix(FieldModel, v))
+}
+
+// ModelHasSuffix applies the HasSuffix predicate on the "model" field.
+func ModelHasSuffix(v string) predicate.UsageDetail {
+	return predicate.UsageDetail(sql.FieldHasSuffix(FieldModel, v))
+}
+
+// ModelIsNil applies the IsNil predicate on the "model" field.
+func ModelIsNil() predicate.UsageDetail {
+	return predicate.UsageDetail(sql.FieldIsNull(FieldModel))
+}
+
+// ModelNotNil applies the NotNil predicate on the "model" field.
+func ModelNotNil() predicate.UsageDetail {
+	return predicate.UsageDetail(sql.FieldNotNull(FieldModel))
+}
+
+// ModelEqualFold applies the EqualFold predicate on the "model" field.
+func ModelEqualFold(v string) predicate.UsageDetail {
+	return predicate.UsageDetail(sql.FieldEqualFold(FieldModel, v))
+}
+
+// ModelContainsFold applies the ContainsFold predicate on the "model" field.
+func ModelContainsFold(v string) predicate.UsageDetail {
+	return predicate.UsageDetail(sql.FieldContainsFold(FieldModel, v))
+}
+
+// CreditsEQ applies the EQ predicate on the "credits" field.
+func CreditsEQ(v float64) predicate.UsageDetail {
+	return predicate.UsageDetail(sql.FieldEQ(FieldCredits, v))
+}
+
+// CreditsNEQ applies the NEQ predicate on the "credits" field.
+func CreditsNEQ(v float64) predicate.UsageDetail {
+	return predicate.UsageDetail(sql.FieldNEQ(FieldCredits, v))
+}
+
+// CreditsIn applies the In predicate on the "credits" field.
+func CreditsIn(vs ...float64) predicate.UsageDetail {
+	return predicate.UsageDetail(sql.FieldIn(FieldCredits, vs...))
+}
+
+// CreditsNotIn applies the NotIn predicate on the "credits" field.
+func CreditsNotIn(vs ...float64) predicate.UsageDetail {
+	return predicate.UsageDetail(sql.FieldNotIn(FieldCredits, vs...))
+}
+
+// CreditsGT applies the GT predicate on the "credits" field.
+func CreditsGT(v float64) predicate.UsageDetail {
+	return predicate.UsageDetail(sql.FieldGT(FieldCredits, v))
+}
+
+// CreditsGTE applies the GTE predicate on the "credits" field.
+func CreditsGTE(v float64) predicate.UsageDetail {
+	return predicate.UsageDetail(sql.FieldGTE(FieldCredits, v))
+}
+
+// CreditsLT applies the LT predicate on the "credits" field.
+func CreditsLT(v float64) predicate.UsageDetail {
+	return predicate.UsageDetail(sql.FieldLT(FieldCredits, v))
+}
+
+// CreditsLTE applies the LTE predicate on the "credits" field.
+func CreditsLTE(v float64) predicate.UsageDetail {
+	return predicate.UsageDetail(sql.FieldLTE(FieldCredits, v))
+}
+
+// CreditsIsNil applies the IsNil predicate on the "credits" field.
+func CreditsIsNil() predicate.UsageDetail {
+	return predicate.UsageDetail(sql.FieldIsNull(FieldCredits))
+}
+
+// CreditsNotNil applies the NotNil predicate on the "credits" field.
+func CreditsNotNil() predicate.UsageDetail {
+	return predicate.UsageDetail(sql.FieldNotNull(FieldCredits))
+}
+
 // And groups predicates with the AND operator between them.
 func And(predicates ...predicate.UsageDetail) predicate.UsageDetail {
 	return predicate.UsageDetail(sql.AndPredicates(predicates...))

+ 180 - 0
ent/usagedetail_create.go

@@ -225,6 +225,34 @@ func (udc *UsageDetailCreate) SetNillableOrganizationID(u *uint64) *UsageDetailC
 	return udc
 }
 
+// SetModel sets the "model" field.
+func (udc *UsageDetailCreate) SetModel(s string) *UsageDetailCreate {
+	udc.mutation.SetModel(s)
+	return udc
+}
+
+// SetNillableModel sets the "model" field if the given value is not nil.
+func (udc *UsageDetailCreate) SetNillableModel(s *string) *UsageDetailCreate {
+	if s != nil {
+		udc.SetModel(*s)
+	}
+	return udc
+}
+
+// SetCredits sets the "credits" field.
+func (udc *UsageDetailCreate) SetCredits(f float64) *UsageDetailCreate {
+	udc.mutation.SetCredits(f)
+	return udc
+}
+
+// SetNillableCredits sets the "credits" field if the given value is not nil.
+func (udc *UsageDetailCreate) SetNillableCredits(f *float64) *UsageDetailCreate {
+	if f != nil {
+		udc.SetCredits(*f)
+	}
+	return udc
+}
+
 // SetID sets the "id" field.
 func (udc *UsageDetailCreate) SetID(u uint64) *UsageDetailCreate {
 	udc.mutation.SetID(u)
@@ -322,6 +350,10 @@ func (udc *UsageDetailCreate) defaults() {
 		v := usagedetail.DefaultOrganizationID
 		udc.mutation.SetOrganizationID(v)
 	}
+	if _, ok := udc.mutation.Model(); !ok {
+		v := usagedetail.DefaultModel
+		udc.mutation.SetModel(v)
+	}
 }
 
 // check runs all checks and user-defined validators on the builder.
@@ -440,6 +472,14 @@ func (udc *UsageDetailCreate) createSpec() (*UsageDetail, *sqlgraph.CreateSpec)
 		_spec.SetField(usagedetail.FieldOrganizationID, field.TypeUint64, value)
 		_node.OrganizationID = value
 	}
+	if value, ok := udc.mutation.Model(); ok {
+		_spec.SetField(usagedetail.FieldModel, field.TypeString, value)
+		_node.Model = value
+	}
+	if value, ok := udc.mutation.Credits(); ok {
+		_spec.SetField(usagedetail.FieldCredits, field.TypeFloat64, value)
+		_node.Credits = value
+	}
 	return _node, _spec
 }
 
@@ -756,6 +796,48 @@ func (u *UsageDetailUpsert) ClearOrganizationID() *UsageDetailUpsert {
 	return u
 }
 
+// SetModel sets the "model" field.
+func (u *UsageDetailUpsert) SetModel(v string) *UsageDetailUpsert {
+	u.Set(usagedetail.FieldModel, v)
+	return u
+}
+
+// UpdateModel sets the "model" field to the value that was provided on create.
+func (u *UsageDetailUpsert) UpdateModel() *UsageDetailUpsert {
+	u.SetExcluded(usagedetail.FieldModel)
+	return u
+}
+
+// ClearModel clears the value of the "model" field.
+func (u *UsageDetailUpsert) ClearModel() *UsageDetailUpsert {
+	u.SetNull(usagedetail.FieldModel)
+	return u
+}
+
+// SetCredits sets the "credits" field.
+func (u *UsageDetailUpsert) SetCredits(v float64) *UsageDetailUpsert {
+	u.Set(usagedetail.FieldCredits, v)
+	return u
+}
+
+// UpdateCredits sets the "credits" field to the value that was provided on create.
+func (u *UsageDetailUpsert) UpdateCredits() *UsageDetailUpsert {
+	u.SetExcluded(usagedetail.FieldCredits)
+	return u
+}
+
+// AddCredits adds v to the "credits" field.
+func (u *UsageDetailUpsert) AddCredits(v float64) *UsageDetailUpsert {
+	u.Add(usagedetail.FieldCredits, v)
+	return u
+}
+
+// ClearCredits clears the value of the "credits" field.
+func (u *UsageDetailUpsert) ClearCredits() *UsageDetailUpsert {
+	u.SetNull(usagedetail.FieldCredits)
+	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:
 //
@@ -1115,6 +1197,55 @@ func (u *UsageDetailUpsertOne) ClearOrganizationID() *UsageDetailUpsertOne {
 	})
 }
 
+// SetModel sets the "model" field.
+func (u *UsageDetailUpsertOne) SetModel(v string) *UsageDetailUpsertOne {
+	return u.Update(func(s *UsageDetailUpsert) {
+		s.SetModel(v)
+	})
+}
+
+// UpdateModel sets the "model" field to the value that was provided on create.
+func (u *UsageDetailUpsertOne) UpdateModel() *UsageDetailUpsertOne {
+	return u.Update(func(s *UsageDetailUpsert) {
+		s.UpdateModel()
+	})
+}
+
+// ClearModel clears the value of the "model" field.
+func (u *UsageDetailUpsertOne) ClearModel() *UsageDetailUpsertOne {
+	return u.Update(func(s *UsageDetailUpsert) {
+		s.ClearModel()
+	})
+}
+
+// SetCredits sets the "credits" field.
+func (u *UsageDetailUpsertOne) SetCredits(v float64) *UsageDetailUpsertOne {
+	return u.Update(func(s *UsageDetailUpsert) {
+		s.SetCredits(v)
+	})
+}
+
+// AddCredits adds v to the "credits" field.
+func (u *UsageDetailUpsertOne) AddCredits(v float64) *UsageDetailUpsertOne {
+	return u.Update(func(s *UsageDetailUpsert) {
+		s.AddCredits(v)
+	})
+}
+
+// UpdateCredits sets the "credits" field to the value that was provided on create.
+func (u *UsageDetailUpsertOne) UpdateCredits() *UsageDetailUpsertOne {
+	return u.Update(func(s *UsageDetailUpsert) {
+		s.UpdateCredits()
+	})
+}
+
+// ClearCredits clears the value of the "credits" field.
+func (u *UsageDetailUpsertOne) ClearCredits() *UsageDetailUpsertOne {
+	return u.Update(func(s *UsageDetailUpsert) {
+		s.ClearCredits()
+	})
+}
+
 // Exec executes the query.
 func (u *UsageDetailUpsertOne) Exec(ctx context.Context) error {
 	if len(u.create.conflict) == 0 {
@@ -1640,6 +1771,55 @@ func (u *UsageDetailUpsertBulk) ClearOrganizationID() *UsageDetailUpsertBulk {
 	})
 }
 
+// SetModel sets the "model" field.
+func (u *UsageDetailUpsertBulk) SetModel(v string) *UsageDetailUpsertBulk {
+	return u.Update(func(s *UsageDetailUpsert) {
+		s.SetModel(v)
+	})
+}
+
+// UpdateModel sets the "model" field to the value that was provided on create.
+func (u *UsageDetailUpsertBulk) UpdateModel() *UsageDetailUpsertBulk {
+	return u.Update(func(s *UsageDetailUpsert) {
+		s.UpdateModel()
+	})
+}
+
+// ClearModel clears the value of the "model" field.
+func (u *UsageDetailUpsertBulk) ClearModel() *UsageDetailUpsertBulk {
+	return u.Update(func(s *UsageDetailUpsert) {
+		s.ClearModel()
+	})
+}
+
+// SetCredits sets the "credits" field.
+func (u *UsageDetailUpsertBulk) SetCredits(v float64) *UsageDetailUpsertBulk {
+	return u.Update(func(s *UsageDetailUpsert) {
+		s.SetCredits(v)
+	})
+}
+
+// AddCredits adds v to the "credits" field.
+func (u *UsageDetailUpsertBulk) AddCredits(v float64) *UsageDetailUpsertBulk {
+	return u.Update(func(s *UsageDetailUpsert) {
+		s.AddCredits(v)
+	})
+}
+
+// UpdateCredits sets the "credits" field to the value that was provided on create.
+func (u *UsageDetailUpsertBulk) UpdateCredits() *UsageDetailUpsertBulk {
+	return u.Update(func(s *UsageDetailUpsert) {
+		s.UpdateCredits()
+	})
+}
+
+// ClearCredits clears the value of the "credits" field.
+func (u *UsageDetailUpsertBulk) ClearCredits() *UsageDetailUpsertBulk {
+	return u.Update(func(s *UsageDetailUpsert) {
+		s.ClearCredits()
+	})
+}
+
 // Exec executes the query.
 func (u *UsageDetailUpsertBulk) Exec(ctx context.Context) error {
 	if u.create.err != nil {

+ 124 - 0
ent/usagedetail_update.go

@@ -321,6 +321,53 @@ func (udu *UsageDetailUpdate) ClearOrganizationID() *UsageDetailUpdate {
 	return udu
 }
 
+// SetModel sets the "model" field.
+func (udu *UsageDetailUpdate) SetModel(s string) *UsageDetailUpdate {
+	udu.mutation.SetModel(s)
+	return udu
+}
+
+// SetNillableModel sets the "model" field if the given value is not nil.
+func (udu *UsageDetailUpdate) SetNillableModel(s *string) *UsageDetailUpdate {
+	if s != nil {
+		udu.SetModel(*s)
+	}
+	return udu
+}
+
+// ClearModel clears the value of the "model" field.
+func (udu *UsageDetailUpdate) ClearModel() *UsageDetailUpdate {
+	udu.mutation.ClearModel()
+	return udu
+}
+
+// SetCredits sets the "credits" field.
+func (udu *UsageDetailUpdate) SetCredits(f float64) *UsageDetailUpdate {
+	udu.mutation.ResetCredits()
+	udu.mutation.SetCredits(f)
+	return udu
+}
+
+// SetNillableCredits sets the "credits" field if the given value is not nil.
+func (udu *UsageDetailUpdate) SetNillableCredits(f *float64) *UsageDetailUpdate {
+	if f != nil {
+		udu.SetCredits(*f)
+	}
+	return udu
+}
+
+// AddCredits adds f to the "credits" field.
+func (udu *UsageDetailUpdate) AddCredits(f float64) *UsageDetailUpdate {
+	udu.mutation.AddCredits(f)
+	return udu
+}
+
+// ClearCredits clears the value of the "credits" field.
+func (udu *UsageDetailUpdate) ClearCredits() *UsageDetailUpdate {
+	udu.mutation.ClearCredits()
+	return udu
+}
+
 // Mutation returns the UsageDetailMutation object of the builder.
 func (udu *UsageDetailUpdate) Mutation() *UsageDetailMutation {
 	return udu.mutation
@@ -461,6 +508,21 @@ func (udu *UsageDetailUpdate) sqlSave(ctx context.Context) (n int, err error) {
 	if udu.mutation.OrganizationIDCleared() {
 		_spec.ClearField(usagedetail.FieldOrganizationID, field.TypeUint64)
 	}
+	if value, ok := udu.mutation.Model(); ok {
+		_spec.SetField(usagedetail.FieldModel, field.TypeString, value)
+	}
+	if udu.mutation.ModelCleared() {
+		_spec.ClearField(usagedetail.FieldModel, field.TypeString)
+	}
+	if value, ok := udu.mutation.Credits(); ok {
+		_spec.SetField(usagedetail.FieldCredits, field.TypeFloat64, value)
+	}
+	if value, ok := udu.mutation.AddedCredits(); ok {
+		_spec.AddField(usagedetail.FieldCredits, field.TypeFloat64, value)
+	}
+	if udu.mutation.CreditsCleared() {
+		_spec.ClearField(usagedetail.FieldCredits, field.TypeFloat64)
+	}
 	if n, err = sqlgraph.UpdateNodes(ctx, udu.driver, _spec); err != nil {
 		if _, ok := err.(*sqlgraph.NotFoundError); ok {
 			err = &NotFoundError{usagedetail.Label}
@@ -773,6 +835,53 @@ func (uduo *UsageDetailUpdateOne) ClearOrganizationID() *UsageDetailUpdateOne {
 	return uduo
 }
 
+// SetModel sets the "model" field.
+func (uduo *UsageDetailUpdateOne) SetModel(s string) *UsageDetailUpdateOne {
+	uduo.mutation.SetModel(s)
+	return uduo
+}
+
+// SetNillableModel sets the "model" field if the given value is not nil.
+func (uduo *UsageDetailUpdateOne) SetNillableModel(s *string) *UsageDetailUpdateOne {
+	if s != nil {
+		uduo.SetModel(*s)
+	}
+	return uduo
+}
+
+// ClearModel clears the value of the "model" field.
+func (uduo *UsageDetailUpdateOne) ClearModel() *UsageDetailUpdateOne {
+	uduo.mutation.ClearModel()
+	return uduo
+}
+
+// SetCredits sets the "credits" field.
+func (uduo *UsageDetailUpdateOne) SetCredits(f float64) *UsageDetailUpdateOne {
+	uduo.mutation.ResetCredits()
+	uduo.mutation.SetCredits(f)
+	return uduo
+}
+
+// SetNillableCredits sets the "credits" field if the given value is not nil.
+func (uduo *UsageDetailUpdateOne) SetNillableCredits(f *float64) *UsageDetailUpdateOne {
+	if f != nil {
+		uduo.SetCredits(*f)
+	}
+	return uduo
+}
+
+// AddCredits adds f to the "credits" field.
+func (uduo *UsageDetailUpdateOne) AddCredits(f float64) *UsageDetailUpdateOne {
+	uduo.mutation.AddCredits(f)
+	return uduo
+}
+
+// ClearCredits clears the value of the "credits" field.
+func (uduo *UsageDetailUpdateOne) ClearCredits() *UsageDetailUpdateOne {
+	uduo.mutation.ClearCredits()
+	return uduo
+}
+
 // Mutation returns the UsageDetailMutation object of the builder.
 func (uduo *UsageDetailUpdateOne) Mutation() *UsageDetailMutation {
 	return uduo.mutation
@@ -943,6 +1052,21 @@ func (uduo *UsageDetailUpdateOne) sqlSave(ctx context.Context) (_node *UsageDeta
 	if uduo.mutation.OrganizationIDCleared() {
 		_spec.ClearField(usagedetail.FieldOrganizationID, field.TypeUint64)
 	}
+	if value, ok := uduo.mutation.Model(); ok {
+		_spec.SetField(usagedetail.FieldModel, field.TypeString, value)
+	}
+	if uduo.mutation.ModelCleared() {
+		_spec.ClearField(usagedetail.FieldModel, field.TypeString)
+	}
+	if value, ok := uduo.mutation.Credits(); ok {
+		_spec.SetField(usagedetail.FieldCredits, field.TypeFloat64, value)
+	}
+	if value, ok := uduo.mutation.AddedCredits(); ok {
+		_spec.AddField(usagedetail.FieldCredits, field.TypeFloat64, value)
+	}
+	if uduo.mutation.CreditsCleared() {
+		_spec.ClearField(usagedetail.FieldCredits, field.TypeFloat64)
+	}
 	_node = &UsageDetail{config: uduo.config}
 	_spec.Assign = _node.assignValues
 	_spec.ScanValues = _node.scanValues

+ 14 - 1
ent/usagestatisticday.go

@@ -52,7 +52,9 @@ type UsageStatisticDay struct {
 	// 新增用户数
 	NewUser int64 `json:"new_user,omitempty"`
 	// 标签分布
-	LabelDist    []custom_types.LabelDist `json:"label_dist,omitempty"`
+	LabelDist []custom_types.LabelDist `json:"label_dist,omitempty"`
+	// 消耗积分
+	ConsumeCoin  float64 `json:"consume_coin,omitempty"`
 	selectValues sql.SelectValues
 }
 
@@ -63,6 +65,8 @@ func (*UsageStatisticDay) scanValues(columns []string) ([]any, error) {
 		switch columns[i] {
 		case usagestatisticday.FieldLabelDist:
 			values[i] = new([]byte)
+		case usagestatisticday.FieldConsumeCoin:
+			values[i] = new(sql.NullFloat64)
 		case usagestatisticday.FieldID, usagestatisticday.FieldStatus, usagestatisticday.FieldAddtime, usagestatisticday.FieldType, usagestatisticday.FieldOrganizationID, usagestatisticday.FieldAiResponse, usagestatisticday.FieldSopRun, usagestatisticday.FieldTotalFriend, usagestatisticday.FieldTotalGroup, usagestatisticday.FieldAccountBalance, usagestatisticday.FieldConsumeToken, usagestatisticday.FieldActiveUser, usagestatisticday.FieldNewUser:
 			values[i] = new(sql.NullInt64)
 		case usagestatisticday.FieldBotID:
@@ -194,6 +198,12 @@ func (usd *UsageStatisticDay) assignValues(columns []string, values []any) error
 					return fmt.Errorf("unmarshal field label_dist: %w", err)
 				}
 			}
+		case usagestatisticday.FieldConsumeCoin:
+			if value, ok := values[i].(*sql.NullFloat64); !ok {
+				return fmt.Errorf("unexpected type %T for field consume_coin", values[i])
+			} else if value.Valid {
+				usd.ConsumeCoin = value.Float64
+			}
 		default:
 			usd.selectValues.Set(columns[i], values[i])
 		}
@@ -280,6 +290,9 @@ func (usd *UsageStatisticDay) String() string {
 	builder.WriteString(", ")
 	builder.WriteString("label_dist=")
 	builder.WriteString(fmt.Sprintf("%v", usd.LabelDist))
+	builder.WriteString(", ")
+	builder.WriteString("consume_coin=")
+	builder.WriteString(fmt.Sprintf("%v", usd.ConsumeCoin))
 	builder.WriteByte(')')
 	return builder.String()
 }

+ 10 - 0
ent/usagestatisticday/usagestatisticday.go

@@ -48,6 +48,8 @@ const (
 	FieldNewUser = "new_user"
 	// FieldLabelDist holds the string denoting the label_dist field in the database.
 	FieldLabelDist = "label_dist"
+	// FieldConsumeCoin holds the string denoting the consume_coin field in the database.
+	FieldConsumeCoin = "consume_coin"
 	// Table holds the table name of the usagestatisticday in the database.
 	Table = "usage_statistic_day"
 )
@@ -72,6 +74,7 @@ var Columns = []string{
 	FieldActiveUser,
 	FieldNewUser,
 	FieldLabelDist,
+	FieldConsumeCoin,
 }
 
 // ValidColumn reports if the column name is valid (part of the table columns).
@@ -100,6 +103,8 @@ var (
 	UpdateDefaultUpdatedAt func() time.Time
 	// DefaultStatus holds the default value on creation for the "status" field.
 	DefaultStatus uint8
+	// DefaultConsumeCoin holds the default value on creation for the "consume_coin" field.
+	DefaultConsumeCoin float64
 )
 
 // OrderOption defines the ordering options for the UsageStatisticDay queries.
@@ -189,3 +194,8 @@ func ByActiveUser(opts ...sql.OrderTermOption) OrderOption {
 func ByNewUser(opts ...sql.OrderTermOption) OrderOption {
 	return sql.OrderByField(FieldNewUser, opts...).ToFunc()
 }
+
+// ByConsumeCoin orders the results by the consume_coin field.
+func ByConsumeCoin(opts ...sql.OrderTermOption) OrderOption {
+	return sql.OrderByField(FieldConsumeCoin, opts...).ToFunc()
+}

+ 55 - 0
ent/usagestatisticday/where.go

@@ -134,6 +134,11 @@ func NewUser(v int64) predicate.UsageStatisticDay {
 	return predicate.UsageStatisticDay(sql.FieldEQ(FieldNewUser, v))
 }
 
+// ConsumeCoin applies equality check predicate on the "consume_coin" field. It's identical to ConsumeCoinEQ.
+func ConsumeCoin(v float64) predicate.UsageStatisticDay {
+	return predicate.UsageStatisticDay(sql.FieldEQ(FieldConsumeCoin, v))
+}
+
 // CreatedAtEQ applies the EQ predicate on the "created_at" field.
 func CreatedAtEQ(v time.Time) predicate.UsageStatisticDay {
 	return predicate.UsageStatisticDay(sql.FieldEQ(FieldCreatedAt, v))
@@ -839,6 +844,56 @@ func NewUserLTE(v int64) predicate.UsageStatisticDay {
 	return predicate.UsageStatisticDay(sql.FieldLTE(FieldNewUser, v))
 }
 
+// ConsumeCoinEQ applies the EQ predicate on the "consume_coin" field.
+func ConsumeCoinEQ(v float64) predicate.UsageStatisticDay {
+	return predicate.UsageStatisticDay(sql.FieldEQ(FieldConsumeCoin, v))
+}
+
+// ConsumeCoinNEQ applies the NEQ predicate on the "consume_coin" field.
+func ConsumeCoinNEQ(v float64) predicate.UsageStatisticDay {
+	return predicate.UsageStatisticDay(sql.FieldNEQ(FieldConsumeCoin, v))
+}
+
+// ConsumeCoinIn applies the In predicate on the "consume_coin" field.
+func ConsumeCoinIn(vs ...float64) predicate.UsageStatisticDay {
+	return predicate.UsageStatisticDay(sql.FieldIn(FieldConsumeCoin, vs...))
+}
+
+// ConsumeCoinNotIn applies the NotIn predicate on the "consume_coin" field.
+func ConsumeCoinNotIn(vs ...float64) predicate.UsageStatisticDay {
+	return predicate.UsageStatisticDay(sql.FieldNotIn(FieldConsumeCoin, vs...))
+}
+
+// ConsumeCoinGT applies the GT predicate on the "consume_coin" field.
+func ConsumeCoinGT(v float64) predicate.UsageStatisticDay {
+	return predicate.UsageStatisticDay(sql.FieldGT(FieldConsumeCoin, v))
+}
+
+// ConsumeCoinGTE applies the GTE predicate on the "consume_coin" field.
+func ConsumeCoinGTE(v float64) predicate.UsageStatisticDay {
+	return predicate.UsageStatisticDay(sql.FieldGTE(FieldConsumeCoin, v))
+}
+
+// ConsumeCoinLT applies the LT predicate on the "consume_coin" field.
+func ConsumeCoinLT(v float64) predicate.UsageStatisticDay {
+	return predicate.UsageStatisticDay(sql.FieldLT(FieldConsumeCoin, v))
+}
+
+// ConsumeCoinLTE applies the LTE predicate on the "consume_coin" field.
+func ConsumeCoinLTE(v float64) predicate.UsageStatisticDay {
+	return predicate.UsageStatisticDay(sql.FieldLTE(FieldConsumeCoin, v))
+}
+
+// ConsumeCoinIsNil applies the IsNil predicate on the "consume_coin" field.
+func ConsumeCoinIsNil() predicate.UsageStatisticDay {
+	return predicate.UsageStatisticDay(sql.FieldIsNull(FieldConsumeCoin))
+}
+
+// ConsumeCoinNotNil applies the NotNil predicate on the "consume_coin" field.
+func ConsumeCoinNotNil() predicate.UsageStatisticDay {
+	return predicate.UsageStatisticDay(sql.FieldNotNull(FieldConsumeCoin))
+}
+
 // And groups predicates with the AND operator between them.
 func And(predicates ...predicate.UsageStatisticDay) predicate.UsageStatisticDay {
 	return predicate.UsageStatisticDay(sql.AndPredicates(predicates...))

+ 102 - 0
ent/usagestatisticday_create.go

@@ -173,6 +173,20 @@ func (usdc *UsageStatisticDayCreate) SetLabelDist(ctd []custom_types.LabelDist)
 	return usdc
 }
 
+// SetConsumeCoin sets the "consume_coin" field.
+func (usdc *UsageStatisticDayCreate) SetConsumeCoin(f float64) *UsageStatisticDayCreate {
+	usdc.mutation.SetConsumeCoin(f)
+	return usdc
+}
+
+// SetNillableConsumeCoin sets the "consume_coin" field if the given value is not nil.
+func (usdc *UsageStatisticDayCreate) SetNillableConsumeCoin(f *float64) *UsageStatisticDayCreate {
+	if f != nil {
+		usdc.SetConsumeCoin(*f)
+	}
+	return usdc
+}
+
 // SetID sets the "id" field.
 func (usdc *UsageStatisticDayCreate) SetID(u uint64) *UsageStatisticDayCreate {
 	usdc.mutation.SetID(u)
@@ -234,6 +248,10 @@ func (usdc *UsageStatisticDayCreate) defaults() error {
 		v := usagestatisticday.DefaultStatus
 		usdc.mutation.SetStatus(v)
 	}
+	if _, ok := usdc.mutation.ConsumeCoin(); !ok {
+		v := usagestatisticday.DefaultConsumeCoin
+		usdc.mutation.SetConsumeCoin(v)
+	}
 	return nil
 }
 
@@ -379,6 +397,10 @@ func (usdc *UsageStatisticDayCreate) createSpec() (*UsageStatisticDay, *sqlgraph
 		_spec.SetField(usagestatisticday.FieldLabelDist, field.TypeJSON, value)
 		_node.LabelDist = value
 	}
+	if value, ok := usdc.mutation.ConsumeCoin(); ok {
+		_spec.SetField(usagestatisticday.FieldConsumeCoin, field.TypeFloat64, value)
+		_node.ConsumeCoin = value
+	}
 	return _node, _spec
 }
 
@@ -719,6 +741,30 @@ func (u *UsageStatisticDayUpsert) UpdateLabelDist() *UsageStatisticDayUpsert {
 	return u
 }
 
+// SetConsumeCoin sets the "consume_coin" field.
+func (u *UsageStatisticDayUpsert) SetConsumeCoin(v float64) *UsageStatisticDayUpsert {
+	u.Set(usagestatisticday.FieldConsumeCoin, v)
+	return u
+}
+
+// UpdateConsumeCoin sets the "consume_coin" field to the value that was provided on create.
+func (u *UsageStatisticDayUpsert) UpdateConsumeCoin() *UsageStatisticDayUpsert {
+	u.SetExcluded(usagestatisticday.FieldConsumeCoin)
+	return u
+}
+
+// AddConsumeCoin adds v to the "consume_coin" field.
+func (u *UsageStatisticDayUpsert) AddConsumeCoin(v float64) *UsageStatisticDayUpsert {
+	u.Add(usagestatisticday.FieldConsumeCoin, v)
+	return u
+}
+
+// ClearConsumeCoin clears the value of the "consume_coin" field.
+func (u *UsageStatisticDayUpsert) ClearConsumeCoin() *UsageStatisticDayUpsert {
+	u.SetNull(usagestatisticday.FieldConsumeCoin)
+	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:
 //
@@ -1106,6 +1152,34 @@ func (u *UsageStatisticDayUpsertOne) UpdateLabelDist() *UsageStatisticDayUpsertO
 	})
 }
 
+// SetConsumeCoin sets the "consume_coin" field.
+func (u *UsageStatisticDayUpsertOne) SetConsumeCoin(v float64) *UsageStatisticDayUpsertOne {
+	return u.Update(func(s *UsageStatisticDayUpsert) {
+		s.SetConsumeCoin(v)
+	})
+}
+
+// AddConsumeCoin adds v to the "consume_coin" field.
+func (u *UsageStatisticDayUpsertOne) AddConsumeCoin(v float64) *UsageStatisticDayUpsertOne {
+	return u.Update(func(s *UsageStatisticDayUpsert) {
+		s.AddConsumeCoin(v)
+	})
+}
+
+// UpdateConsumeCoin sets the "consume_coin" field to the value that was provided on create.
+func (u *UsageStatisticDayUpsertOne) UpdateConsumeCoin() *UsageStatisticDayUpsertOne {
+	return u.Update(func(s *UsageStatisticDayUpsert) {
+		s.UpdateConsumeCoin()
+	})
+}
+
+// ClearConsumeCoin clears the value of the "consume_coin" field.
+func (u *UsageStatisticDayUpsertOne) ClearConsumeCoin() *UsageStatisticDayUpsertOne {
+	return u.Update(func(s *UsageStatisticDayUpsert) {
+		s.ClearConsumeCoin()
+	})
+}
+
 // Exec executes the query.
 func (u *UsageStatisticDayUpsertOne) Exec(ctx context.Context) error {
 	if len(u.create.conflict) == 0 {
@@ -1659,6 +1733,34 @@ func (u *UsageStatisticDayUpsertBulk) UpdateLabelDist() *UsageStatisticDayUpsert
 	})
 }
 
+// SetConsumeCoin sets the "consume_coin" field.
+func (u *UsageStatisticDayUpsertBulk) SetConsumeCoin(v float64) *UsageStatisticDayUpsertBulk {
+	return u.Update(func(s *UsageStatisticDayUpsert) {
+		s.SetConsumeCoin(v)
+	})
+}
+
+// AddConsumeCoin adds v to the "consume_coin" field.
+func (u *UsageStatisticDayUpsertBulk) AddConsumeCoin(v float64) *UsageStatisticDayUpsertBulk {
+	return u.Update(func(s *UsageStatisticDayUpsert) {
+		s.AddConsumeCoin(v)
+	})
+}
+
+// UpdateConsumeCoin sets the "consume_coin" field to the value that was provided on create.
+func (u *UsageStatisticDayUpsertBulk) UpdateConsumeCoin() *UsageStatisticDayUpsertBulk {
+	return u.Update(func(s *UsageStatisticDayUpsert) {
+		s.UpdateConsumeCoin()
+	})
+}
+
+// ClearConsumeCoin clears the value of the "consume_coin" field.
+func (u *UsageStatisticDayUpsertBulk) ClearConsumeCoin() *UsageStatisticDayUpsertBulk {
+	return u.Update(func(s *UsageStatisticDayUpsert) {
+		s.ClearConsumeCoin()
+	})
+}
+
 // Exec executes the query.
 func (u *UsageStatisticDayUpsertBulk) Exec(ctx context.Context) error {
 	if u.create.err != nil {

+ 72 - 0
ent/usagestatisticday_update.go

@@ -352,6 +352,33 @@ func (usdu *UsageStatisticDayUpdate) AppendLabelDist(ctd []custom_types.LabelDis
 	return usdu
 }
 
+// SetConsumeCoin sets the "consume_coin" field.
+func (usdu *UsageStatisticDayUpdate) SetConsumeCoin(f float64) *UsageStatisticDayUpdate {
+	usdu.mutation.ResetConsumeCoin()
+	usdu.mutation.SetConsumeCoin(f)
+	return usdu
+}
+
+// SetNillableConsumeCoin sets the "consume_coin" field if the given value is not nil.
+func (usdu *UsageStatisticDayUpdate) SetNillableConsumeCoin(f *float64) *UsageStatisticDayUpdate {
+	if f != nil {
+		usdu.SetConsumeCoin(*f)
+	}
+	return usdu
+}
+
+// AddConsumeCoin adds f to the "consume_coin" field.
+func (usdu *UsageStatisticDayUpdate) AddConsumeCoin(f float64) *UsageStatisticDayUpdate {
+	usdu.mutation.AddConsumeCoin(f)
+	return usdu
+}
+
+// ClearConsumeCoin clears the value of the "consume_coin" field.
+func (usdu *UsageStatisticDayUpdate) ClearConsumeCoin() *UsageStatisticDayUpdate {
+	usdu.mutation.ClearConsumeCoin()
+	return usdu
+}
+
 // Mutation returns the UsageStatisticDayMutation object of the builder.
 func (usdu *UsageStatisticDayUpdate) Mutation() *UsageStatisticDayMutation {
 	return usdu.mutation
@@ -509,6 +536,15 @@ func (usdu *UsageStatisticDayUpdate) sqlSave(ctx context.Context) (n int, err er
 			sqljson.Append(u, usagestatisticday.FieldLabelDist, value)
 		})
 	}
+	if value, ok := usdu.mutation.ConsumeCoin(); ok {
+		_spec.SetField(usagestatisticday.FieldConsumeCoin, field.TypeFloat64, value)
+	}
+	if value, ok := usdu.mutation.AddedConsumeCoin(); ok {
+		_spec.AddField(usagestatisticday.FieldConsumeCoin, field.TypeFloat64, value)
+	}
+	if usdu.mutation.ConsumeCoinCleared() {
+		_spec.ClearField(usagestatisticday.FieldConsumeCoin, field.TypeFloat64)
+	}
 	if n, err = sqlgraph.UpdateNodes(ctx, usdu.driver, _spec); err != nil {
 		if _, ok := err.(*sqlgraph.NotFoundError); ok {
 			err = &NotFoundError{usagestatisticday.Label}
@@ -851,6 +887,33 @@ func (usduo *UsageStatisticDayUpdateOne) AppendLabelDist(ctd []custom_types.Labe
 	return usduo
 }
 
+// SetConsumeCoin sets the "consume_coin" field.
+func (usduo *UsageStatisticDayUpdateOne) SetConsumeCoin(f float64) *UsageStatisticDayUpdateOne {
+	usduo.mutation.ResetConsumeCoin()
+	usduo.mutation.SetConsumeCoin(f)
+	return usduo
+}
+
+// SetNillableConsumeCoin sets the "consume_coin" field if the given value is not nil.
+func (usduo *UsageStatisticDayUpdateOne) SetNillableConsumeCoin(f *float64) *UsageStatisticDayUpdateOne {
+	if f != nil {
+		usduo.SetConsumeCoin(*f)
+	}
+	return usduo
+}
+
+// AddConsumeCoin adds f to the "consume_coin" field.
+func (usduo *UsageStatisticDayUpdateOne) AddConsumeCoin(f float64) *UsageStatisticDayUpdateOne {
+	usduo.mutation.AddConsumeCoin(f)
+	return usduo
+}
+
+// ClearConsumeCoin clears the value of the "consume_coin" field.
+func (usduo *UsageStatisticDayUpdateOne) ClearConsumeCoin() *UsageStatisticDayUpdateOne {
+	usduo.mutation.ClearConsumeCoin()
+	return usduo
+}
+
 // Mutation returns the UsageStatisticDayMutation object of the builder.
 func (usduo *UsageStatisticDayUpdateOne) Mutation() *UsageStatisticDayMutation {
 	return usduo.mutation
@@ -1038,6 +1101,15 @@ func (usduo *UsageStatisticDayUpdateOne) sqlSave(ctx context.Context) (_node *Us
 			sqljson.Append(u, usagestatisticday.FieldLabelDist, value)
 		})
 	}
+	if value, ok := usduo.mutation.ConsumeCoin(); ok {
+		_spec.SetField(usagestatisticday.FieldConsumeCoin, field.TypeFloat64, value)
+	}
+	if value, ok := usduo.mutation.AddedConsumeCoin(); ok {
+		_spec.AddField(usagestatisticday.FieldConsumeCoin, field.TypeFloat64, value)
+	}
+	if usduo.mutation.ConsumeCoinCleared() {
+		_spec.ClearField(usagestatisticday.FieldConsumeCoin, field.TypeFloat64)
+	}
 	_node = &UsageStatisticDay{config: usduo.config}
 	_spec.Assign = _node.assignValues
 	_spec.ScanValues = _node.scanValues

+ 14 - 1
ent/usagestatistichour.go

@@ -52,7 +52,9 @@ type UsageStatisticHour struct {
 	// 新增用户数
 	NewUser int64 `json:"new_user,omitempty"`
 	// 标签分布
-	LabelDist    []custom_types.LabelDist `json:"label_dist,omitempty"`
+	LabelDist []custom_types.LabelDist `json:"label_dist,omitempty"`
+	// 消耗积分
+	ConsumeCoin  float64 `json:"consume_coin,omitempty"`
 	selectValues sql.SelectValues
 }
 
@@ -63,6 +65,8 @@ func (*UsageStatisticHour) scanValues(columns []string) ([]any, error) {
 		switch columns[i] {
 		case usagestatistichour.FieldLabelDist:
 			values[i] = new([]byte)
+		case usagestatistichour.FieldConsumeCoin:
+			values[i] = new(sql.NullFloat64)
 		case usagestatistichour.FieldID, usagestatistichour.FieldStatus, usagestatistichour.FieldAddtime, usagestatistichour.FieldType, usagestatistichour.FieldOrganizationID, usagestatistichour.FieldAiResponse, usagestatistichour.FieldSopRun, usagestatistichour.FieldTotalFriend, usagestatistichour.FieldTotalGroup, usagestatistichour.FieldAccountBalance, usagestatistichour.FieldConsumeToken, usagestatistichour.FieldActiveUser, usagestatistichour.FieldNewUser:
 			values[i] = new(sql.NullInt64)
 		case usagestatistichour.FieldBotID:
@@ -194,6 +198,12 @@ func (ush *UsageStatisticHour) assignValues(columns []string, values []any) erro
 					return fmt.Errorf("unmarshal field label_dist: %w", err)
 				}
 			}
+		case usagestatistichour.FieldConsumeCoin:
+			if value, ok := values[i].(*sql.NullFloat64); !ok {
+				return fmt.Errorf("unexpected type %T for field consume_coin", values[i])
+			} else if value.Valid {
+				ush.ConsumeCoin = value.Float64
+			}
 		default:
 			ush.selectValues.Set(columns[i], values[i])
 		}
@@ -280,6 +290,9 @@ func (ush *UsageStatisticHour) String() string {
 	builder.WriteString(", ")
 	builder.WriteString("label_dist=")
 	builder.WriteString(fmt.Sprintf("%v", ush.LabelDist))
+	builder.WriteString(", ")
+	builder.WriteString("consume_coin=")
+	builder.WriteString(fmt.Sprintf("%v", ush.ConsumeCoin))
 	builder.WriteByte(')')
 	return builder.String()
 }

+ 10 - 0
ent/usagestatistichour/usagestatistichour.go

@@ -48,6 +48,8 @@ const (
 	FieldNewUser = "new_user"
 	// FieldLabelDist holds the string denoting the label_dist field in the database.
 	FieldLabelDist = "label_dist"
+	// FieldConsumeCoin holds the string denoting the consume_coin field in the database.
+	FieldConsumeCoin = "consume_coin"
 	// Table holds the table name of the usagestatistichour in the database.
 	Table = "usage_statistic_hour"
 )
@@ -72,6 +74,7 @@ var Columns = []string{
 	FieldActiveUser,
 	FieldNewUser,
 	FieldLabelDist,
+	FieldConsumeCoin,
 }
 
 // ValidColumn reports if the column name is valid (part of the table columns).
@@ -100,6 +103,8 @@ var (
 	UpdateDefaultUpdatedAt func() time.Time
 	// DefaultStatus holds the default value on creation for the "status" field.
 	DefaultStatus uint8
+	// DefaultConsumeCoin holds the default value on creation for the "consume_coin" field.
+	DefaultConsumeCoin float64
 )
 
 // OrderOption defines the ordering options for the UsageStatisticHour queries.
@@ -189,3 +194,8 @@ func ByActiveUser(opts ...sql.OrderTermOption) OrderOption {
 func ByNewUser(opts ...sql.OrderTermOption) OrderOption {
 	return sql.OrderByField(FieldNewUser, opts...).ToFunc()
 }
+
+// ByConsumeCoin orders the results by the consume_coin field.
+func ByConsumeCoin(opts ...sql.OrderTermOption) OrderOption {
+	return sql.OrderByField(FieldConsumeCoin, opts...).ToFunc()
+}

+ 55 - 0
ent/usagestatistichour/where.go

@@ -134,6 +134,11 @@ func NewUser(v int64) predicate.UsageStatisticHour {
 	return predicate.UsageStatisticHour(sql.FieldEQ(FieldNewUser, v))
 }
 
+// ConsumeCoin applies equality check predicate on the "consume_coin" field. It's identical to ConsumeCoinEQ.
+func ConsumeCoin(v float64) predicate.UsageStatisticHour {
+	return predicate.UsageStatisticHour(sql.FieldEQ(FieldConsumeCoin, v))
+}
+
 // CreatedAtEQ applies the EQ predicate on the "created_at" field.
 func CreatedAtEQ(v time.Time) predicate.UsageStatisticHour {
 	return predicate.UsageStatisticHour(sql.FieldEQ(FieldCreatedAt, v))
@@ -839,6 +844,56 @@ func NewUserLTE(v int64) predicate.UsageStatisticHour {
 	return predicate.UsageStatisticHour(sql.FieldLTE(FieldNewUser, v))
 }
 
+// ConsumeCoinEQ applies the EQ predicate on the "consume_coin" field.
+func ConsumeCoinEQ(v float64) predicate.UsageStatisticHour {
+	return predicate.UsageStatisticHour(sql.FieldEQ(FieldConsumeCoin, v))
+}
+
+// ConsumeCoinNEQ applies the NEQ predicate on the "consume_coin" field.
+func ConsumeCoinNEQ(v float64) predicate.UsageStatisticHour {
+	return predicate.UsageStatisticHour(sql.FieldNEQ(FieldConsumeCoin, v))
+}
+
+// ConsumeCoinIn applies the In predicate on the "consume_coin" field.
+func ConsumeCoinIn(vs ...float64) predicate.UsageStatisticHour {
+	return predicate.UsageStatisticHour(sql.FieldIn(FieldConsumeCoin, vs...))
+}
+
+// ConsumeCoinNotIn applies the NotIn predicate on the "consume_coin" field.
+func ConsumeCoinNotIn(vs ...float64) predicate.UsageStatisticHour {
+	return predicate.UsageStatisticHour(sql.FieldNotIn(FieldConsumeCoin, vs...))
+}
+
+// ConsumeCoinGT applies the GT predicate on the "consume_coin" field.
+func ConsumeCoinGT(v float64) predicate.UsageStatisticHour {
+	return predicate.UsageStatisticHour(sql.FieldGT(FieldConsumeCoin, v))
+}
+
+// ConsumeCoinGTE applies the GTE predicate on the "consume_coin" field.
+func ConsumeCoinGTE(v float64) predicate.UsageStatisticHour {
+	return predicate.UsageStatisticHour(sql.FieldGTE(FieldConsumeCoin, v))
+}
+
+// ConsumeCoinLT applies the LT predicate on the "consume_coin" field.
+func ConsumeCoinLT(v float64) predicate.UsageStatisticHour {
+	return predicate.UsageStatisticHour(sql.FieldLT(FieldConsumeCoin, v))
+}
+
+// ConsumeCoinLTE applies the LTE predicate on the "consume_coin" field.
+func ConsumeCoinLTE(v float64) predicate.UsageStatisticHour {
+	return predicate.UsageStatisticHour(sql.FieldLTE(FieldConsumeCoin, v))
+}
+
+// ConsumeCoinIsNil applies the IsNil predicate on the "consume_coin" field.
+func ConsumeCoinIsNil() predicate.UsageStatisticHour {
+	return predicate.UsageStatisticHour(sql.FieldIsNull(FieldConsumeCoin))
+}
+
+// ConsumeCoinNotNil applies the NotNil predicate on the "consume_coin" field.
+func ConsumeCoinNotNil() predicate.UsageStatisticHour {
+	return predicate.UsageStatisticHour(sql.FieldNotNull(FieldConsumeCoin))
+}
+
 // And groups predicates with the AND operator between them.
 func And(predicates ...predicate.UsageStatisticHour) predicate.UsageStatisticHour {
 	return predicate.UsageStatisticHour(sql.AndPredicates(predicates...))

+ 102 - 0
ent/usagestatistichour_create.go

@@ -173,6 +173,20 @@ func (ushc *UsageStatisticHourCreate) SetLabelDist(ctd []custom_types.LabelDist)
 	return ushc
 }
 
+// SetConsumeCoin sets the "consume_coin" field.
+func (ushc *UsageStatisticHourCreate) SetConsumeCoin(f float64) *UsageStatisticHourCreate {
+	ushc.mutation.SetConsumeCoin(f)
+	return ushc
+}
+
+// SetNillableConsumeCoin sets the "consume_coin" field if the given value is not nil.
+func (ushc *UsageStatisticHourCreate) SetNillableConsumeCoin(f *float64) *UsageStatisticHourCreate {
+	if f != nil {
+		ushc.SetConsumeCoin(*f)
+	}
+	return ushc
+}
+
 // SetID sets the "id" field.
 func (ushc *UsageStatisticHourCreate) SetID(u uint64) *UsageStatisticHourCreate {
 	ushc.mutation.SetID(u)
@@ -234,6 +248,10 @@ func (ushc *UsageStatisticHourCreate) defaults() error {
 		v := usagestatistichour.DefaultStatus
 		ushc.mutation.SetStatus(v)
 	}
+	if _, ok := ushc.mutation.ConsumeCoin(); !ok {
+		v := usagestatistichour.DefaultConsumeCoin
+		ushc.mutation.SetConsumeCoin(v)
+	}
 	return nil
 }
 
@@ -379,6 +397,10 @@ func (ushc *UsageStatisticHourCreate) createSpec() (*UsageStatisticHour, *sqlgra
 		_spec.SetField(usagestatistichour.FieldLabelDist, field.TypeJSON, value)
 		_node.LabelDist = value
 	}
+	if value, ok := ushc.mutation.ConsumeCoin(); ok {
+		_spec.SetField(usagestatistichour.FieldConsumeCoin, field.TypeFloat64, value)
+		_node.ConsumeCoin = value
+	}
 	return _node, _spec
 }
 
@@ -719,6 +741,30 @@ func (u *UsageStatisticHourUpsert) UpdateLabelDist() *UsageStatisticHourUpsert {
 	return u
 }
 
+// SetConsumeCoin sets the "consume_coin" field.
+func (u *UsageStatisticHourUpsert) SetConsumeCoin(v float64) *UsageStatisticHourUpsert {
+	u.Set(usagestatistichour.FieldConsumeCoin, v)
+	return u
+}
+
+// UpdateConsumeCoin sets the "consume_coin" field to the value that was provided on create.
+func (u *UsageStatisticHourUpsert) UpdateConsumeCoin() *UsageStatisticHourUpsert {
+	u.SetExcluded(usagestatistichour.FieldConsumeCoin)
+	return u
+}
+
+// AddConsumeCoin adds v to the "consume_coin" field.
+func (u *UsageStatisticHourUpsert) AddConsumeCoin(v float64) *UsageStatisticHourUpsert {
+	u.Add(usagestatistichour.FieldConsumeCoin, v)
+	return u
+}
+
+// ClearConsumeCoin clears the value of the "consume_coin" field.
+func (u *UsageStatisticHourUpsert) ClearConsumeCoin() *UsageStatisticHourUpsert {
+	u.SetNull(usagestatistichour.FieldConsumeCoin)
+	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:
 //
@@ -1106,6 +1152,34 @@ func (u *UsageStatisticHourUpsertOne) UpdateLabelDist() *UsageStatisticHourUpser
 	})
 }
 
+// SetConsumeCoin sets the "consume_coin" field.
+func (u *UsageStatisticHourUpsertOne) SetConsumeCoin(v float64) *UsageStatisticHourUpsertOne {
+	return u.Update(func(s *UsageStatisticHourUpsert) {
+		s.SetConsumeCoin(v)
+	})
+}
+
+// AddConsumeCoin adds v to the "consume_coin" field.
+func (u *UsageStatisticHourUpsertOne) AddConsumeCoin(v float64) *UsageStatisticHourUpsertOne {
+	return u.Update(func(s *UsageStatisticHourUpsert) {
+		s.AddConsumeCoin(v)
+	})
+}
+
+// UpdateConsumeCoin sets the "consume_coin" field to the value that was provided on create.
+func (u *UsageStatisticHourUpsertOne) UpdateConsumeCoin() *UsageStatisticHourUpsertOne {
+	return u.Update(func(s *UsageStatisticHourUpsert) {
+		s.UpdateConsumeCoin()
+	})
+}
+
+// ClearConsumeCoin clears the value of the "consume_coin" field.
+func (u *UsageStatisticHourUpsertOne) ClearConsumeCoin() *UsageStatisticHourUpsertOne {
+	return u.Update(func(s *UsageStatisticHourUpsert) {
+		s.ClearConsumeCoin()
+	})
+}
+
 // Exec executes the query.
 func (u *UsageStatisticHourUpsertOne) Exec(ctx context.Context) error {
 	if len(u.create.conflict) == 0 {
@@ -1659,6 +1733,34 @@ func (u *UsageStatisticHourUpsertBulk) UpdateLabelDist() *UsageStatisticHourUpse
 	})
 }
 
+// SetConsumeCoin sets the "consume_coin" field.
+func (u *UsageStatisticHourUpsertBulk) SetConsumeCoin(v float64) *UsageStatisticHourUpsertBulk {
+	return u.Update(func(s *UsageStatisticHourUpsert) {
+		s.SetConsumeCoin(v)
+	})
+}
+
+// AddConsumeCoin adds v to the "consume_coin" field.
+func (u *UsageStatisticHourUpsertBulk) AddConsumeCoin(v float64) *UsageStatisticHourUpsertBulk {
+	return u.Update(func(s *UsageStatisticHourUpsert) {
+		s.AddConsumeCoin(v)
+	})
+}
+
+// UpdateConsumeCoin sets the "consume_coin" field to the value that was provided on create.
+func (u *UsageStatisticHourUpsertBulk) UpdateConsumeCoin() *UsageStatisticHourUpsertBulk {
+	return u.Update(func(s *UsageStatisticHourUpsert) {
+		s.UpdateConsumeCoin()
+	})
+}
+
+// ClearConsumeCoin clears the value of the "consume_coin" field.
+func (u *UsageStatisticHourUpsertBulk) ClearConsumeCoin() *UsageStatisticHourUpsertBulk {
+	return u.Update(func(s *UsageStatisticHourUpsert) {
+		s.ClearConsumeCoin()
+	})
+}
+
 // Exec executes the query.
 func (u *UsageStatisticHourUpsertBulk) Exec(ctx context.Context) error {
 	if u.create.err != nil {

+ 72 - 0
ent/usagestatistichour_update.go

@@ -352,6 +352,33 @@ func (ushu *UsageStatisticHourUpdate) AppendLabelDist(ctd []custom_types.LabelDi
 	return ushu
 }
 
+// SetConsumeCoin sets the "consume_coin" field.
+func (ushu *UsageStatisticHourUpdate) SetConsumeCoin(f float64) *UsageStatisticHourUpdate {
+	ushu.mutation.ResetConsumeCoin()
+	ushu.mutation.SetConsumeCoin(f)
+	return ushu
+}
+
+// SetNillableConsumeCoin sets the "consume_coin" field if the given value is not nil.
+func (ushu *UsageStatisticHourUpdate) SetNillableConsumeCoin(f *float64) *UsageStatisticHourUpdate {
+	if f != nil {
+		ushu.SetConsumeCoin(*f)
+	}
+	return ushu
+}
+
+// AddConsumeCoin adds f to the "consume_coin" field.
+func (ushu *UsageStatisticHourUpdate) AddConsumeCoin(f float64) *UsageStatisticHourUpdate {
+	ushu.mutation.AddConsumeCoin(f)
+	return ushu
+}
+
+// ClearConsumeCoin clears the value of the "consume_coin" field.
+func (ushu *UsageStatisticHourUpdate) ClearConsumeCoin() *UsageStatisticHourUpdate {
+	ushu.mutation.ClearConsumeCoin()
+	return ushu
+}
+
 // Mutation returns the UsageStatisticHourMutation object of the builder.
 func (ushu *UsageStatisticHourUpdate) Mutation() *UsageStatisticHourMutation {
 	return ushu.mutation
@@ -509,6 +536,15 @@ func (ushu *UsageStatisticHourUpdate) sqlSave(ctx context.Context) (n int, err e
 			sqljson.Append(u, usagestatistichour.FieldLabelDist, value)
 		})
 	}
+	if value, ok := ushu.mutation.ConsumeCoin(); ok {
+		_spec.SetField(usagestatistichour.FieldConsumeCoin, field.TypeFloat64, value)
+	}
+	if value, ok := ushu.mutation.AddedConsumeCoin(); ok {
+		_spec.AddField(usagestatistichour.FieldConsumeCoin, field.TypeFloat64, value)
+	}
+	if ushu.mutation.ConsumeCoinCleared() {
+		_spec.ClearField(usagestatistichour.FieldConsumeCoin, field.TypeFloat64)
+	}
 	if n, err = sqlgraph.UpdateNodes(ctx, ushu.driver, _spec); err != nil {
 		if _, ok := err.(*sqlgraph.NotFoundError); ok {
 			err = &NotFoundError{usagestatistichour.Label}
@@ -851,6 +887,33 @@ func (ushuo *UsageStatisticHourUpdateOne) AppendLabelDist(ctd []custom_types.Lab
 	return ushuo
 }
 
+// SetConsumeCoin sets the "consume_coin" field.
+func (ushuo *UsageStatisticHourUpdateOne) SetConsumeCoin(f float64) *UsageStatisticHourUpdateOne {
+	ushuo.mutation.ResetConsumeCoin()
+	ushuo.mutation.SetConsumeCoin(f)
+	return ushuo
+}
+
+// SetNillableConsumeCoin sets the "consume_coin" field if the given value is not nil.
+func (ushuo *UsageStatisticHourUpdateOne) SetNillableConsumeCoin(f *float64) *UsageStatisticHourUpdateOne {
+	if f != nil {
+		ushuo.SetConsumeCoin(*f)
+	}
+	return ushuo
+}
+
+// AddConsumeCoin adds f to the "consume_coin" field.
+func (ushuo *UsageStatisticHourUpdateOne) AddConsumeCoin(f float64) *UsageStatisticHourUpdateOne {
+	ushuo.mutation.AddConsumeCoin(f)
+	return ushuo
+}
+
+// ClearConsumeCoin clears the value of the "consume_coin" field.
+func (ushuo *UsageStatisticHourUpdateOne) ClearConsumeCoin() *UsageStatisticHourUpdateOne {
+	ushuo.mutation.ClearConsumeCoin()
+	return ushuo
+}
+
 // Mutation returns the UsageStatisticHourMutation object of the builder.
 func (ushuo *UsageStatisticHourUpdateOne) Mutation() *UsageStatisticHourMutation {
 	return ushuo.mutation
@@ -1038,6 +1101,15 @@ func (ushuo *UsageStatisticHourUpdateOne) sqlSave(ctx context.Context) (_node *U
 			sqljson.Append(u, usagestatistichour.FieldLabelDist, value)
 		})
 	}
+	if value, ok := ushuo.mutation.ConsumeCoin(); ok {
+		_spec.SetField(usagestatistichour.FieldConsumeCoin, field.TypeFloat64, value)
+	}
+	if value, ok := ushuo.mutation.AddedConsumeCoin(); ok {
+		_spec.AddField(usagestatistichour.FieldConsumeCoin, field.TypeFloat64, value)
+	}
+	if ushuo.mutation.ConsumeCoinCleared() {
+		_spec.ClearField(usagestatistichour.FieldConsumeCoin, field.TypeFloat64)
+	}
 	_node = &UsageStatisticHour{config: ushuo.config}
 	_spec.Assign = _node.assignValues
 	_spec.ScanValues = _node.scanValues

+ 14 - 1
ent/usagestatisticmonth.go

@@ -52,7 +52,9 @@ type UsageStatisticMonth struct {
 	// 新增用户数
 	NewUser int64 `json:"new_user,omitempty"`
 	// 标签分布
-	LabelDist    []custom_types.LabelDist `json:"label_dist,omitempty"`
+	LabelDist []custom_types.LabelDist `json:"label_dist,omitempty"`
+	// 消耗积分
+	ConsumeCoin  float64 `json:"consume_coin,omitempty"`
 	selectValues sql.SelectValues
 }
 
@@ -63,6 +65,8 @@ func (*UsageStatisticMonth) scanValues(columns []string) ([]any, error) {
 		switch columns[i] {
 		case usagestatisticmonth.FieldLabelDist:
 			values[i] = new([]byte)
+		case usagestatisticmonth.FieldConsumeCoin:
+			values[i] = new(sql.NullFloat64)
 		case usagestatisticmonth.FieldID, usagestatisticmonth.FieldStatus, usagestatisticmonth.FieldAddtime, usagestatisticmonth.FieldType, usagestatisticmonth.FieldOrganizationID, usagestatisticmonth.FieldAiResponse, usagestatisticmonth.FieldSopRun, usagestatisticmonth.FieldTotalFriend, usagestatisticmonth.FieldTotalGroup, usagestatisticmonth.FieldAccountBalance, usagestatisticmonth.FieldConsumeToken, usagestatisticmonth.FieldActiveUser, usagestatisticmonth.FieldNewUser:
 			values[i] = new(sql.NullInt64)
 		case usagestatisticmonth.FieldBotID:
@@ -194,6 +198,12 @@ func (usm *UsageStatisticMonth) assignValues(columns []string, values []any) err
 					return fmt.Errorf("unmarshal field label_dist: %w", err)
 				}
 			}
+		case usagestatisticmonth.FieldConsumeCoin:
+			if value, ok := values[i].(*sql.NullFloat64); !ok {
+				return fmt.Errorf("unexpected type %T for field consume_coin", values[i])
+			} else if value.Valid {
+				usm.ConsumeCoin = value.Float64
+			}
 		default:
 			usm.selectValues.Set(columns[i], values[i])
 		}
@@ -280,6 +290,9 @@ func (usm *UsageStatisticMonth) String() string {
 	builder.WriteString(", ")
 	builder.WriteString("label_dist=")
 	builder.WriteString(fmt.Sprintf("%v", usm.LabelDist))
+	builder.WriteString(", ")
+	builder.WriteString("consume_coin=")
+	builder.WriteString(fmt.Sprintf("%v", usm.ConsumeCoin))
 	builder.WriteByte(')')
 	return builder.String()
 }

+ 10 - 0
ent/usagestatisticmonth/usagestatisticmonth.go

@@ -48,6 +48,8 @@ const (
 	FieldNewUser = "new_user"
 	// FieldLabelDist holds the string denoting the label_dist field in the database.
 	FieldLabelDist = "label_dist"
+	// FieldConsumeCoin holds the string denoting the consume_coin field in the database.
+	FieldConsumeCoin = "consume_coin"
 	// Table holds the table name of the usagestatisticmonth in the database.
 	Table = "usage_statistic_month"
 )
@@ -72,6 +74,7 @@ var Columns = []string{
 	FieldActiveUser,
 	FieldNewUser,
 	FieldLabelDist,
+	FieldConsumeCoin,
 }
 
 // ValidColumn reports if the column name is valid (part of the table columns).
@@ -100,6 +103,8 @@ var (
 	UpdateDefaultUpdatedAt func() time.Time
 	// DefaultStatus holds the default value on creation for the "status" field.
 	DefaultStatus uint8
+	// DefaultConsumeCoin holds the default value on creation for the "consume_coin" field.
+	DefaultConsumeCoin float64
 )
 
 // OrderOption defines the ordering options for the UsageStatisticMonth queries.
@@ -189,3 +194,8 @@ func ByActiveUser(opts ...sql.OrderTermOption) OrderOption {
 func ByNewUser(opts ...sql.OrderTermOption) OrderOption {
 	return sql.OrderByField(FieldNewUser, opts...).ToFunc()
 }
+
+// ByConsumeCoin orders the results by the consume_coin field.
+func ByConsumeCoin(opts ...sql.OrderTermOption) OrderOption {
+	return sql.OrderByField(FieldConsumeCoin, opts...).ToFunc()
+}

+ 55 - 0
ent/usagestatisticmonth/where.go

@@ -134,6 +134,11 @@ func NewUser(v int64) predicate.UsageStatisticMonth {
 	return predicate.UsageStatisticMonth(sql.FieldEQ(FieldNewUser, v))
 }
 
+// ConsumeCoin applies equality check predicate on the "consume_coin" field. It's identical to ConsumeCoinEQ.
+func ConsumeCoin(v float64) predicate.UsageStatisticMonth {
+	return predicate.UsageStatisticMonth(sql.FieldEQ(FieldConsumeCoin, v))
+}
+
 // CreatedAtEQ applies the EQ predicate on the "created_at" field.
 func CreatedAtEQ(v time.Time) predicate.UsageStatisticMonth {
 	return predicate.UsageStatisticMonth(sql.FieldEQ(FieldCreatedAt, v))
@@ -839,6 +844,56 @@ func NewUserLTE(v int64) predicate.UsageStatisticMonth {
 	return predicate.UsageStatisticMonth(sql.FieldLTE(FieldNewUser, v))
 }
 
+// ConsumeCoinEQ applies the EQ predicate on the "consume_coin" field.
+func ConsumeCoinEQ(v float64) predicate.UsageStatisticMonth {
+	return predicate.UsageStatisticMonth(sql.FieldEQ(FieldConsumeCoin, v))
+}
+
+// ConsumeCoinNEQ applies the NEQ predicate on the "consume_coin" field.
+func ConsumeCoinNEQ(v float64) predicate.UsageStatisticMonth {
+	return predicate.UsageStatisticMonth(sql.FieldNEQ(FieldConsumeCoin, v))
+}
+
+// ConsumeCoinIn applies the In predicate on the "consume_coin" field.
+func ConsumeCoinIn(vs ...float64) predicate.UsageStatisticMonth {
+	return predicate.UsageStatisticMonth(sql.FieldIn(FieldConsumeCoin, vs...))
+}
+
+// ConsumeCoinNotIn applies the NotIn predicate on the "consume_coin" field.
+func ConsumeCoinNotIn(vs ...float64) predicate.UsageStatisticMonth {
+	return predicate.UsageStatisticMonth(sql.FieldNotIn(FieldConsumeCoin, vs...))
+}
+
+// ConsumeCoinGT applies the GT predicate on the "consume_coin" field.
+func ConsumeCoinGT(v float64) predicate.UsageStatisticMonth {
+	return predicate.UsageStatisticMonth(sql.FieldGT(FieldConsumeCoin, v))
+}
+
+// ConsumeCoinGTE applies the GTE predicate on the "consume_coin" field.
+func ConsumeCoinGTE(v float64) predicate.UsageStatisticMonth {
+	return predicate.UsageStatisticMonth(sql.FieldGTE(FieldConsumeCoin, v))
+}
+
+// ConsumeCoinLT applies the LT predicate on the "consume_coin" field.
+func ConsumeCoinLT(v float64) predicate.UsageStatisticMonth {
+	return predicate.UsageStatisticMonth(sql.FieldLT(FieldConsumeCoin, v))
+}
+
+// ConsumeCoinLTE applies the LTE predicate on the "consume_coin" field.
+func ConsumeCoinLTE(v float64) predicate.UsageStatisticMonth {
+	return predicate.UsageStatisticMonth(sql.FieldLTE(FieldConsumeCoin, v))
+}
+
+// ConsumeCoinIsNil applies the IsNil predicate on the "consume_coin" field.
+func ConsumeCoinIsNil() predicate.UsageStatisticMonth {
+	return predicate.UsageStatisticMonth(sql.FieldIsNull(FieldConsumeCoin))
+}
+
+// ConsumeCoinNotNil applies the NotNil predicate on the "consume_coin" field.
+func ConsumeCoinNotNil() predicate.UsageStatisticMonth {
+	return predicate.UsageStatisticMonth(sql.FieldNotNull(FieldConsumeCoin))
+}
+
 // And groups predicates with the AND operator between them.
 func And(predicates ...predicate.UsageStatisticMonth) predicate.UsageStatisticMonth {
 	return predicate.UsageStatisticMonth(sql.AndPredicates(predicates...))

+ 102 - 0
ent/usagestatisticmonth_create.go

@@ -173,6 +173,20 @@ func (usmc *UsageStatisticMonthCreate) SetLabelDist(ctd []custom_types.LabelDist
 	return usmc
 }
 
+// SetConsumeCoin sets the "consume_coin" field.
+func (usmc *UsageStatisticMonthCreate) SetConsumeCoin(f float64) *UsageStatisticMonthCreate {
+	usmc.mutation.SetConsumeCoin(f)
+	return usmc
+}
+
+// SetNillableConsumeCoin sets the "consume_coin" field if the given value is not nil.
+func (usmc *UsageStatisticMonthCreate) SetNillableConsumeCoin(f *float64) *UsageStatisticMonthCreate {
+	if f != nil {
+		usmc.SetConsumeCoin(*f)
+	}
+	return usmc
+}
+
 // SetID sets the "id" field.
 func (usmc *UsageStatisticMonthCreate) SetID(u uint64) *UsageStatisticMonthCreate {
 	usmc.mutation.SetID(u)
@@ -234,6 +248,10 @@ func (usmc *UsageStatisticMonthCreate) defaults() error {
 		v := usagestatisticmonth.DefaultStatus
 		usmc.mutation.SetStatus(v)
 	}
+	if _, ok := usmc.mutation.ConsumeCoin(); !ok {
+		v := usagestatisticmonth.DefaultConsumeCoin
+		usmc.mutation.SetConsumeCoin(v)
+	}
 	return nil
 }
 
@@ -379,6 +397,10 @@ func (usmc *UsageStatisticMonthCreate) createSpec() (*UsageStatisticMonth, *sqlg
 		_spec.SetField(usagestatisticmonth.FieldLabelDist, field.TypeJSON, value)
 		_node.LabelDist = value
 	}
+	if value, ok := usmc.mutation.ConsumeCoin(); ok {
+		_spec.SetField(usagestatisticmonth.FieldConsumeCoin, field.TypeFloat64, value)
+		_node.ConsumeCoin = value
+	}
 	return _node, _spec
 }
 
@@ -719,6 +741,30 @@ func (u *UsageStatisticMonthUpsert) UpdateLabelDist() *UsageStatisticMonthUpsert
 	return u
 }
 
+// SetConsumeCoin sets the "consume_coin" field.
+func (u *UsageStatisticMonthUpsert) SetConsumeCoin(v float64) *UsageStatisticMonthUpsert {
+	u.Set(usagestatisticmonth.FieldConsumeCoin, v)
+	return u
+}
+
+// UpdateConsumeCoin sets the "consume_coin" field to the value that was provided on create.
+func (u *UsageStatisticMonthUpsert) UpdateConsumeCoin() *UsageStatisticMonthUpsert {
+	u.SetExcluded(usagestatisticmonth.FieldConsumeCoin)
+	return u
+}
+
+// AddConsumeCoin adds v to the "consume_coin" field.
+func (u *UsageStatisticMonthUpsert) AddConsumeCoin(v float64) *UsageStatisticMonthUpsert {
+	u.Add(usagestatisticmonth.FieldConsumeCoin, v)
+	return u
+}
+
+// ClearConsumeCoin clears the value of the "consume_coin" field.
+func (u *UsageStatisticMonthUpsert) ClearConsumeCoin() *UsageStatisticMonthUpsert {
+	u.SetNull(usagestatisticmonth.FieldConsumeCoin)
+	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:
 //
@@ -1106,6 +1152,34 @@ func (u *UsageStatisticMonthUpsertOne) UpdateLabelDist() *UsageStatisticMonthUps
 	})
 }
 
+// SetConsumeCoin sets the "consume_coin" field.
+func (u *UsageStatisticMonthUpsertOne) SetConsumeCoin(v float64) *UsageStatisticMonthUpsertOne {
+	return u.Update(func(s *UsageStatisticMonthUpsert) {
+		s.SetConsumeCoin(v)
+	})
+}
+
+// AddConsumeCoin adds v to the "consume_coin" field.
+func (u *UsageStatisticMonthUpsertOne) AddConsumeCoin(v float64) *UsageStatisticMonthUpsertOne {
+	return u.Update(func(s *UsageStatisticMonthUpsert) {
+		s.AddConsumeCoin(v)
+	})
+}
+
+// UpdateConsumeCoin sets the "consume_coin" field to the value that was provided on create.
+func (u *UsageStatisticMonthUpsertOne) UpdateConsumeCoin() *UsageStatisticMonthUpsertOne {
+	return u.Update(func(s *UsageStatisticMonthUpsert) {
+		s.UpdateConsumeCoin()
+	})
+}
+
+// ClearConsumeCoin clears the value of the "consume_coin" field.
+func (u *UsageStatisticMonthUpsertOne) ClearConsumeCoin() *UsageStatisticMonthUpsertOne {
+	return u.Update(func(s *UsageStatisticMonthUpsert) {
+		s.ClearConsumeCoin()
+	})
+}
+
 // Exec executes the query.
 func (u *UsageStatisticMonthUpsertOne) Exec(ctx context.Context) error {
 	if len(u.create.conflict) == 0 {
@@ -1659,6 +1733,34 @@ func (u *UsageStatisticMonthUpsertBulk) UpdateLabelDist() *UsageStatisticMonthUp
 	})
 }
 
+// SetConsumeCoin sets the "consume_coin" field.
+func (u *UsageStatisticMonthUpsertBulk) SetConsumeCoin(v float64) *UsageStatisticMonthUpsertBulk {
+	return u.Update(func(s *UsageStatisticMonthUpsert) {
+		s.SetConsumeCoin(v)
+	})
+}
+
+// AddConsumeCoin adds v to the "consume_coin" field.
+func (u *UsageStatisticMonthUpsertBulk) AddConsumeCoin(v float64) *UsageStatisticMonthUpsertBulk {
+	return u.Update(func(s *UsageStatisticMonthUpsert) {
+		s.AddConsumeCoin(v)
+	})
+}
+
+// UpdateConsumeCoin sets the "consume_coin" field to the value that was provided on create.
+func (u *UsageStatisticMonthUpsertBulk) UpdateConsumeCoin() *UsageStatisticMonthUpsertBulk {
+	return u.Update(func(s *UsageStatisticMonthUpsert) {
+		s.UpdateConsumeCoin()
+	})
+}
+
+// ClearConsumeCoin clears the value of the "consume_coin" field.
+func (u *UsageStatisticMonthUpsertBulk) ClearConsumeCoin() *UsageStatisticMonthUpsertBulk {
+	return u.Update(func(s *UsageStatisticMonthUpsert) {
+		s.ClearConsumeCoin()
+	})
+}
+
 // Exec executes the query.
 func (u *UsageStatisticMonthUpsertBulk) Exec(ctx context.Context) error {
 	if u.create.err != nil {

+ 72 - 0
ent/usagestatisticmonth_update.go

@@ -352,6 +352,33 @@ func (usmu *UsageStatisticMonthUpdate) AppendLabelDist(ctd []custom_types.LabelD
 	return usmu
 }
 
+// SetConsumeCoin sets the "consume_coin" field.
+func (usmu *UsageStatisticMonthUpdate) SetConsumeCoin(f float64) *UsageStatisticMonthUpdate {
+	usmu.mutation.ResetConsumeCoin()
+	usmu.mutation.SetConsumeCoin(f)
+	return usmu
+}
+
+// SetNillableConsumeCoin sets the "consume_coin" field if the given value is not nil.
+func (usmu *UsageStatisticMonthUpdate) SetNillableConsumeCoin(f *float64) *UsageStatisticMonthUpdate {
+	if f != nil {
+		usmu.SetConsumeCoin(*f)
+	}
+	return usmu
+}
+
+// AddConsumeCoin adds f to the "consume_coin" field.
+func (usmu *UsageStatisticMonthUpdate) AddConsumeCoin(f float64) *UsageStatisticMonthUpdate {
+	usmu.mutation.AddConsumeCoin(f)
+	return usmu
+}
+
+// ClearConsumeCoin clears the value of the "consume_coin" field.
+func (usmu *UsageStatisticMonthUpdate) ClearConsumeCoin() *UsageStatisticMonthUpdate {
+	usmu.mutation.ClearConsumeCoin()
+	return usmu
+}
+
 // Mutation returns the UsageStatisticMonthMutation object of the builder.
 func (usmu *UsageStatisticMonthUpdate) Mutation() *UsageStatisticMonthMutation {
 	return usmu.mutation
@@ -509,6 +536,15 @@ func (usmu *UsageStatisticMonthUpdate) sqlSave(ctx context.Context) (n int, err
 			sqljson.Append(u, usagestatisticmonth.FieldLabelDist, value)
 		})
 	}
+	if value, ok := usmu.mutation.ConsumeCoin(); ok {
+		_spec.SetField(usagestatisticmonth.FieldConsumeCoin, field.TypeFloat64, value)
+	}
+	if value, ok := usmu.mutation.AddedConsumeCoin(); ok {
+		_spec.AddField(usagestatisticmonth.FieldConsumeCoin, field.TypeFloat64, value)
+	}
+	if usmu.mutation.ConsumeCoinCleared() {
+		_spec.ClearField(usagestatisticmonth.FieldConsumeCoin, field.TypeFloat64)
+	}
 	if n, err = sqlgraph.UpdateNodes(ctx, usmu.driver, _spec); err != nil {
 		if _, ok := err.(*sqlgraph.NotFoundError); ok {
 			err = &NotFoundError{usagestatisticmonth.Label}
@@ -851,6 +887,33 @@ func (usmuo *UsageStatisticMonthUpdateOne) AppendLabelDist(ctd []custom_types.La
 	return usmuo
 }
 
+// SetConsumeCoin sets the "consume_coin" field.
+func (usmuo *UsageStatisticMonthUpdateOne) SetConsumeCoin(f float64) *UsageStatisticMonthUpdateOne {
+	usmuo.mutation.ResetConsumeCoin()
+	usmuo.mutation.SetConsumeCoin(f)
+	return usmuo
+}
+
+// SetNillableConsumeCoin sets the "consume_coin" field if the given value is not nil.
+func (usmuo *UsageStatisticMonthUpdateOne) SetNillableConsumeCoin(f *float64) *UsageStatisticMonthUpdateOne {
+	if f != nil {
+		usmuo.SetConsumeCoin(*f)
+	}
+	return usmuo
+}
+
+// AddConsumeCoin adds f to the "consume_coin" field.
+func (usmuo *UsageStatisticMonthUpdateOne) AddConsumeCoin(f float64) *UsageStatisticMonthUpdateOne {
+	usmuo.mutation.AddConsumeCoin(f)
+	return usmuo
+}
+
+// ClearConsumeCoin clears the value of the "consume_coin" field.
+func (usmuo *UsageStatisticMonthUpdateOne) ClearConsumeCoin() *UsageStatisticMonthUpdateOne {
+	usmuo.mutation.ClearConsumeCoin()
+	return usmuo
+}
+
 // Mutation returns the UsageStatisticMonthMutation object of the builder.
 func (usmuo *UsageStatisticMonthUpdateOne) Mutation() *UsageStatisticMonthMutation {
 	return usmuo.mutation
@@ -1038,6 +1101,15 @@ func (usmuo *UsageStatisticMonthUpdateOne) sqlSave(ctx context.Context) (_node *
 			sqljson.Append(u, usagestatisticmonth.FieldLabelDist, value)
 		})
 	}
+	if value, ok := usmuo.mutation.ConsumeCoin(); ok {
+		_spec.SetField(usagestatisticmonth.FieldConsumeCoin, field.TypeFloat64, value)
+	}
+	if value, ok := usmuo.mutation.AddedConsumeCoin(); ok {
+		_spec.AddField(usagestatisticmonth.FieldConsumeCoin, field.TypeFloat64, value)
+	}
+	if usmuo.mutation.ConsumeCoinCleared() {
+		_spec.ClearField(usagestatisticmonth.FieldConsumeCoin, field.TypeFloat64)
+	}
 	_node = &UsageStatisticMonth{config: usmuo.config}
 	_spec.Assign = _node.assignValues
 	_spec.ScanValues = _node.scanValues

+ 194 - 0
ent/xunji.go

@@ -0,0 +1,194 @@
+// Code generated by ent, DO NOT EDIT.
+
+package ent
+
+import (
+	"fmt"
+	"strings"
+	"time"
+	"wechat-api/ent/xunji"
+
+	"entgo.io/ent"
+	"entgo.io/ent/dialect/sql"
+)
+
+// Xunji is the model entity for the Xunji schema.
+type Xunji 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"`
+	// AppKey
+	AppKey string `json:"app_key,omitempty"`
+	// AppSecret
+	AppSecret string `json:"app_secret,omitempty"`
+	// Token
+	Token string `json:"token,omitempty"`
+	// 加密key
+	EncodingKey string `json:"encoding_key,omitempty"`
+	// organization_id | 租户ID
+	OrganizationID uint64 `json:"organization_id,omitempty"`
+	selectValues   sql.SelectValues
+}
+
+// scanValues returns the types for scanning values from sql.Rows.
+func (*Xunji) scanValues(columns []string) ([]any, error) {
+	values := make([]any, len(columns))
+	for i := range columns {
+		switch columns[i] {
+		case xunji.FieldID, xunji.FieldStatus, xunji.FieldOrganizationID:
+			values[i] = new(sql.NullInt64)
+		case xunji.FieldAppKey, xunji.FieldAppSecret, xunji.FieldToken, xunji.FieldEncodingKey:
+			values[i] = new(sql.NullString)
+		case xunji.FieldCreatedAt, xunji.FieldUpdatedAt, xunji.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 Xunji fields.
+func (x *Xunji) 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 xunji.FieldID:
+			value, ok := values[i].(*sql.NullInt64)
+			if !ok {
+				return fmt.Errorf("unexpected type %T for field id", value)
+			}
+			x.ID = uint64(value.Int64)
+		case xunji.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 {
+				x.CreatedAt = value.Time
+			}
+		case xunji.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 {
+				x.UpdatedAt = value.Time
+			}
+		case xunji.FieldStatus:
+			if value, ok := values[i].(*sql.NullInt64); !ok {
+				return fmt.Errorf("unexpected type %T for field status", values[i])
+			} else if value.Valid {
+				x.Status = uint8(value.Int64)
+			}
+		case xunji.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 {
+				x.DeletedAt = value.Time
+			}
+		case xunji.FieldAppKey:
+			if value, ok := values[i].(*sql.NullString); !ok {
+				return fmt.Errorf("unexpected type %T for field app_key", values[i])
+			} else if value.Valid {
+				x.AppKey = value.String
+			}
+		case xunji.FieldAppSecret:
+			if value, ok := values[i].(*sql.NullString); !ok {
+				return fmt.Errorf("unexpected type %T for field app_secret", values[i])
+			} else if value.Valid {
+				x.AppSecret = value.String
+			}
+		case xunji.FieldToken:
+			if value, ok := values[i].(*sql.NullString); !ok {
+				return fmt.Errorf("unexpected type %T for field token", values[i])
+			} else if value.Valid {
+				x.Token = value.String
+			}
+		case xunji.FieldEncodingKey:
+			if value, ok := values[i].(*sql.NullString); !ok {
+				return fmt.Errorf("unexpected type %T for field encoding_key", values[i])
+			} else if value.Valid {
+				x.EncodingKey = value.String
+			}
+		case xunji.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 {
+				x.OrganizationID = uint64(value.Int64)
+			}
+		default:
+			x.selectValues.Set(columns[i], values[i])
+		}
+	}
+	return nil
+}
+
+// Value returns the ent.Value that was dynamically selected and assigned to the Xunji.
+// This includes values selected through modifiers, order, etc.
+func (x *Xunji) Value(name string) (ent.Value, error) {
+	return x.selectValues.Get(name)
+}
+
+// Update returns a builder for updating this Xunji.
+// Note that you need to call Xunji.Unwrap() before calling this method if this Xunji
+// was returned from a transaction, and the transaction was committed or rolled back.
+func (x *Xunji) Update() *XunjiUpdateOne {
+	return NewXunjiClient(x.config).UpdateOne(x)
+}
+
+// Unwrap unwraps the Xunji 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 (x *Xunji) Unwrap() *Xunji {
+	_tx, ok := x.config.driver.(*txDriver)
+	if !ok {
+		panic("ent: Xunji is not a transactional entity")
+	}
+	x.config.driver = _tx.drv
+	return x
+}
+
+// String implements the fmt.Stringer.
+func (x *Xunji) String() string {
+	var builder strings.Builder
+	builder.WriteString("Xunji(")
+	builder.WriteString(fmt.Sprintf("id=%v, ", x.ID))
+	builder.WriteString("created_at=")
+	builder.WriteString(x.CreatedAt.Format(time.ANSIC))
+	builder.WriteString(", ")
+	builder.WriteString("updated_at=")
+	builder.WriteString(x.UpdatedAt.Format(time.ANSIC))
+	builder.WriteString(", ")
+	builder.WriteString("status=")
+	builder.WriteString(fmt.Sprintf("%v", x.Status))
+	builder.WriteString(", ")
+	builder.WriteString("deleted_at=")
+	builder.WriteString(x.DeletedAt.Format(time.ANSIC))
+	builder.WriteString(", ")
+	builder.WriteString("app_key=")
+	builder.WriteString(x.AppKey)
+	builder.WriteString(", ")
+	builder.WriteString("app_secret=")
+	builder.WriteString(x.AppSecret)
+	builder.WriteString(", ")
+	builder.WriteString("token=")
+	builder.WriteString(x.Token)
+	builder.WriteString(", ")
+	builder.WriteString("encoding_key=")
+	builder.WriteString(x.EncodingKey)
+	builder.WriteString(", ")
+	builder.WriteString("organization_id=")
+	builder.WriteString(fmt.Sprintf("%v", x.OrganizationID))
+	builder.WriteByte(')')
+	return builder.String()
+}
+
+// Xunjis is a parsable slice of Xunji.
+type Xunjis []*Xunji

+ 635 - 0
ent/xunji/where.go

@@ -0,0 +1,635 @@
+// Code generated by ent, DO NOT EDIT.
+
+package xunji
+
+import (
+	"time"
+	"wechat-api/ent/predicate"
+
+	"entgo.io/ent/dialect/sql"
+)
+
+// ID filters vertices based on their ID field.
+func ID(id uint64) predicate.Xunji {
+	return predicate.Xunji(sql.FieldEQ(FieldID, id))
+}
+
+// IDEQ applies the EQ predicate on the ID field.
+func IDEQ(id uint64) predicate.Xunji {
+	return predicate.Xunji(sql.FieldEQ(FieldID, id))
+}
+
+// IDNEQ applies the NEQ predicate on the ID field.
+func IDNEQ(id uint64) predicate.Xunji {
+	return predicate.Xunji(sql.FieldNEQ(FieldID, id))
+}
+
+// IDIn applies the In predicate on the ID field.
+func IDIn(ids ...uint64) predicate.Xunji {
+	return predicate.Xunji(sql.FieldIn(FieldID, ids...))
+}
+
+// IDNotIn applies the NotIn predicate on the ID field.
+func IDNotIn(ids ...uint64) predicate.Xunji {
+	return predicate.Xunji(sql.FieldNotIn(FieldID, ids...))
+}
+
+// IDGT applies the GT predicate on the ID field.
+func IDGT(id uint64) predicate.Xunji {
+	return predicate.Xunji(sql.FieldGT(FieldID, id))
+}
+
+// IDGTE applies the GTE predicate on the ID field.
+func IDGTE(id uint64) predicate.Xunji {
+	return predicate.Xunji(sql.FieldGTE(FieldID, id))
+}
+
+// IDLT applies the LT predicate on the ID field.
+func IDLT(id uint64) predicate.Xunji {
+	return predicate.Xunji(sql.FieldLT(FieldID, id))
+}
+
+// IDLTE applies the LTE predicate on the ID field.
+func IDLTE(id uint64) predicate.Xunji {
+	return predicate.Xunji(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.Xunji {
+	return predicate.Xunji(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.Xunji {
+	return predicate.Xunji(sql.FieldEQ(FieldUpdatedAt, v))
+}
+
+// Status applies equality check predicate on the "status" field. It's identical to StatusEQ.
+func Status(v uint8) predicate.Xunji {
+	return predicate.Xunji(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.Xunji {
+	return predicate.Xunji(sql.FieldEQ(FieldDeletedAt, v))
+}
+
+// AppKey applies equality check predicate on the "app_key" field. It's identical to AppKeyEQ.
+func AppKey(v string) predicate.Xunji {
+	return predicate.Xunji(sql.FieldEQ(FieldAppKey, v))
+}
+
+// AppSecret applies equality check predicate on the "app_secret" field. It's identical to AppSecretEQ.
+func AppSecret(v string) predicate.Xunji {
+	return predicate.Xunji(sql.FieldEQ(FieldAppSecret, v))
+}
+
+// Token applies equality check predicate on the "token" field. It's identical to TokenEQ.
+func Token(v string) predicate.Xunji {
+	return predicate.Xunji(sql.FieldEQ(FieldToken, v))
+}
+
+// EncodingKey applies equality check predicate on the "encoding_key" field. It's identical to EncodingKeyEQ.
+func EncodingKey(v string) predicate.Xunji {
+	return predicate.Xunji(sql.FieldEQ(FieldEncodingKey, v))
+}
+
+// OrganizationID applies equality check predicate on the "organization_id" field. It's identical to OrganizationIDEQ.
+func OrganizationID(v uint64) predicate.Xunji {
+	return predicate.Xunji(sql.FieldEQ(FieldOrganizationID, v))
+}
+
+// CreatedAtEQ applies the EQ predicate on the "created_at" field.
+func CreatedAtEQ(v time.Time) predicate.Xunji {
+	return predicate.Xunji(sql.FieldEQ(FieldCreatedAt, v))
+}
+
+// CreatedAtNEQ applies the NEQ predicate on the "created_at" field.
+func CreatedAtNEQ(v time.Time) predicate.Xunji {
+	return predicate.Xunji(sql.FieldNEQ(FieldCreatedAt, v))
+}
+
+// CreatedAtIn applies the In predicate on the "created_at" field.
+func CreatedAtIn(vs ...time.Time) predicate.Xunji {
+	return predicate.Xunji(sql.FieldIn(FieldCreatedAt, vs...))
+}
+
+// CreatedAtNotIn applies the NotIn predicate on the "created_at" field.
+func CreatedAtNotIn(vs ...time.Time) predicate.Xunji {
+	return predicate.Xunji(sql.FieldNotIn(FieldCreatedAt, vs...))
+}
+
+// CreatedAtGT applies the GT predicate on the "created_at" field.
+func CreatedAtGT(v time.Time) predicate.Xunji {
+	return predicate.Xunji(sql.FieldGT(FieldCreatedAt, v))
+}
+
+// CreatedAtGTE applies the GTE predicate on the "created_at" field.
+func CreatedAtGTE(v time.Time) predicate.Xunji {
+	return predicate.Xunji(sql.FieldGTE(FieldCreatedAt, v))
+}
+
+// CreatedAtLT applies the LT predicate on the "created_at" field.
+func CreatedAtLT(v time.Time) predicate.Xunji {
+	return predicate.Xunji(sql.FieldLT(FieldCreatedAt, v))
+}
+
+// CreatedAtLTE applies the LTE predicate on the "created_at" field.
+func CreatedAtLTE(v time.Time) predicate.Xunji {
+	return predicate.Xunji(sql.FieldLTE(FieldCreatedAt, v))
+}
+
+// UpdatedAtEQ applies the EQ predicate on the "updated_at" field.
+func UpdatedAtEQ(v time.Time) predicate.Xunji {
+	return predicate.Xunji(sql.FieldEQ(FieldUpdatedAt, v))
+}
+
+// UpdatedAtNEQ applies the NEQ predicate on the "updated_at" field.
+func UpdatedAtNEQ(v time.Time) predicate.Xunji {
+	return predicate.Xunji(sql.FieldNEQ(FieldUpdatedAt, v))
+}
+
+// UpdatedAtIn applies the In predicate on the "updated_at" field.
+func UpdatedAtIn(vs ...time.Time) predicate.Xunji {
+	return predicate.Xunji(sql.FieldIn(FieldUpdatedAt, vs...))
+}
+
+// UpdatedAtNotIn applies the NotIn predicate on the "updated_at" field.
+func UpdatedAtNotIn(vs ...time.Time) predicate.Xunji {
+	return predicate.Xunji(sql.FieldNotIn(FieldUpdatedAt, vs...))
+}
+
+// UpdatedAtGT applies the GT predicate on the "updated_at" field.
+func UpdatedAtGT(v time.Time) predicate.Xunji {
+	return predicate.Xunji(sql.FieldGT(FieldUpdatedAt, v))
+}
+
+// UpdatedAtGTE applies the GTE predicate on the "updated_at" field.
+func UpdatedAtGTE(v time.Time) predicate.Xunji {
+	return predicate.Xunji(sql.FieldGTE(FieldUpdatedAt, v))
+}
+
+// UpdatedAtLT applies the LT predicate on the "updated_at" field.
+func UpdatedAtLT(v time.Time) predicate.Xunji {
+	return predicate.Xunji(sql.FieldLT(FieldUpdatedAt, v))
+}
+
+// UpdatedAtLTE applies the LTE predicate on the "updated_at" field.
+func UpdatedAtLTE(v time.Time) predicate.Xunji {
+	return predicate.Xunji(sql.FieldLTE(FieldUpdatedAt, v))
+}
+
+// StatusEQ applies the EQ predicate on the "status" field.
+func StatusEQ(v uint8) predicate.Xunji {
+	return predicate.Xunji(sql.FieldEQ(FieldStatus, v))
+}
+
+// StatusNEQ applies the NEQ predicate on the "status" field.
+func StatusNEQ(v uint8) predicate.Xunji {
+	return predicate.Xunji(sql.FieldNEQ(FieldStatus, v))
+}
+
+// StatusIn applies the In predicate on the "status" field.
+func StatusIn(vs ...uint8) predicate.Xunji {
+	return predicate.Xunji(sql.FieldIn(FieldStatus, vs...))
+}
+
+// StatusNotIn applies the NotIn predicate on the "status" field.
+func StatusNotIn(vs ...uint8) predicate.Xunji {
+	return predicate.Xunji(sql.FieldNotIn(FieldStatus, vs...))
+}
+
+// StatusGT applies the GT predicate on the "status" field.
+func StatusGT(v uint8) predicate.Xunji {
+	return predicate.Xunji(sql.FieldGT(FieldStatus, v))
+}
+
+// StatusGTE applies the GTE predicate on the "status" field.
+func StatusGTE(v uint8) predicate.Xunji {
+	return predicate.Xunji(sql.FieldGTE(FieldStatus, v))
+}
+
+// StatusLT applies the LT predicate on the "status" field.
+func StatusLT(v uint8) predicate.Xunji {
+	return predicate.Xunji(sql.FieldLT(FieldStatus, v))
+}
+
+// StatusLTE applies the LTE predicate on the "status" field.
+func StatusLTE(v uint8) predicate.Xunji {
+	return predicate.Xunji(sql.FieldLTE(FieldStatus, v))
+}
+
+// StatusIsNil applies the IsNil predicate on the "status" field.
+func StatusIsNil() predicate.Xunji {
+	return predicate.Xunji(sql.FieldIsNull(FieldStatus))
+}
+
+// StatusNotNil applies the NotNil predicate on the "status" field.
+func StatusNotNil() predicate.Xunji {
+	return predicate.Xunji(sql.FieldNotNull(FieldStatus))
+}
+
+// DeletedAtEQ applies the EQ predicate on the "deleted_at" field.
+func DeletedAtEQ(v time.Time) predicate.Xunji {
+	return predicate.Xunji(sql.FieldEQ(FieldDeletedAt, v))
+}
+
+// DeletedAtNEQ applies the NEQ predicate on the "deleted_at" field.
+func DeletedAtNEQ(v time.Time) predicate.Xunji {
+	return predicate.Xunji(sql.FieldNEQ(FieldDeletedAt, v))
+}
+
+// DeletedAtIn applies the In predicate on the "deleted_at" field.
+func DeletedAtIn(vs ...time.Time) predicate.Xunji {
+	return predicate.Xunji(sql.FieldIn(FieldDeletedAt, vs...))
+}
+
+// DeletedAtNotIn applies the NotIn predicate on the "deleted_at" field.
+func DeletedAtNotIn(vs ...time.Time) predicate.Xunji {
+	return predicate.Xunji(sql.FieldNotIn(FieldDeletedAt, vs...))
+}
+
+// DeletedAtGT applies the GT predicate on the "deleted_at" field.
+func DeletedAtGT(v time.Time) predicate.Xunji {
+	return predicate.Xunji(sql.FieldGT(FieldDeletedAt, v))
+}
+
+// DeletedAtGTE applies the GTE predicate on the "deleted_at" field.
+func DeletedAtGTE(v time.Time) predicate.Xunji {
+	return predicate.Xunji(sql.FieldGTE(FieldDeletedAt, v))
+}
+
+// DeletedAtLT applies the LT predicate on the "deleted_at" field.
+func DeletedAtLT(v time.Time) predicate.Xunji {
+	return predicate.Xunji(sql.FieldLT(FieldDeletedAt, v))
+}
+
+// DeletedAtLTE applies the LTE predicate on the "deleted_at" field.
+func DeletedAtLTE(v time.Time) predicate.Xunji {
+	return predicate.Xunji(sql.FieldLTE(FieldDeletedAt, v))
+}
+
+// DeletedAtIsNil applies the IsNil predicate on the "deleted_at" field.
+func DeletedAtIsNil() predicate.Xunji {
+	return predicate.Xunji(sql.FieldIsNull(FieldDeletedAt))
+}
+
+// DeletedAtNotNil applies the NotNil predicate on the "deleted_at" field.
+func DeletedAtNotNil() predicate.Xunji {
+	return predicate.Xunji(sql.FieldNotNull(FieldDeletedAt))
+}
+
+// AppKeyEQ applies the EQ predicate on the "app_key" field.
+func AppKeyEQ(v string) predicate.Xunji {
+	return predicate.Xunji(sql.FieldEQ(FieldAppKey, v))
+}
+
+// AppKeyNEQ applies the NEQ predicate on the "app_key" field.
+func AppKeyNEQ(v string) predicate.Xunji {
+	return predicate.Xunji(sql.FieldNEQ(FieldAppKey, v))
+}
+
+// AppKeyIn applies the In predicate on the "app_key" field.
+func AppKeyIn(vs ...string) predicate.Xunji {
+	return predicate.Xunji(sql.FieldIn(FieldAppKey, vs...))
+}
+
+// AppKeyNotIn applies the NotIn predicate on the "app_key" field.
+func AppKeyNotIn(vs ...string) predicate.Xunji {
+	return predicate.Xunji(sql.FieldNotIn(FieldAppKey, vs...))
+}
+
+// AppKeyGT applies the GT predicate on the "app_key" field.
+func AppKeyGT(v string) predicate.Xunji {
+	return predicate.Xunji(sql.FieldGT(FieldAppKey, v))
+}
+
+// AppKeyGTE applies the GTE predicate on the "app_key" field.
+func AppKeyGTE(v string) predicate.Xunji {
+	return predicate.Xunji(sql.FieldGTE(FieldAppKey, v))
+}
+
+// AppKeyLT applies the LT predicate on the "app_key" field.
+func AppKeyLT(v string) predicate.Xunji {
+	return predicate.Xunji(sql.FieldLT(FieldAppKey, v))
+}
+
+// AppKeyLTE applies the LTE predicate on the "app_key" field.
+func AppKeyLTE(v string) predicate.Xunji {
+	return predicate.Xunji(sql.FieldLTE(FieldAppKey, v))
+}
+
+// AppKeyContains applies the Contains predicate on the "app_key" field.
+func AppKeyContains(v string) predicate.Xunji {
+	return predicate.Xunji(sql.FieldContains(FieldAppKey, v))
+}
+
+// AppKeyHasPrefix applies the HasPrefix predicate on the "app_key" field.
+func AppKeyHasPrefix(v string) predicate.Xunji {
+	return predicate.Xunji(sql.FieldHasPrefix(FieldAppKey, v))
+}
+
+// AppKeyHasSuffix applies the HasSuffix predicate on the "app_key" field.
+func AppKeyHasSuffix(v string) predicate.Xunji {
+	return predicate.Xunji(sql.FieldHasSuffix(FieldAppKey, v))
+}
+
+// AppKeyIsNil applies the IsNil predicate on the "app_key" field.
+func AppKeyIsNil() predicate.Xunji {
+	return predicate.Xunji(sql.FieldIsNull(FieldAppKey))
+}
+
+// AppKeyNotNil applies the NotNil predicate on the "app_key" field.
+func AppKeyNotNil() predicate.Xunji {
+	return predicate.Xunji(sql.FieldNotNull(FieldAppKey))
+}
+
+// AppKeyEqualFold applies the EqualFold predicate on the "app_key" field.
+func AppKeyEqualFold(v string) predicate.Xunji {
+	return predicate.Xunji(sql.FieldEqualFold(FieldAppKey, v))
+}
+
+// AppKeyContainsFold applies the ContainsFold predicate on the "app_key" field.
+func AppKeyContainsFold(v string) predicate.Xunji {
+	return predicate.Xunji(sql.FieldContainsFold(FieldAppKey, v))
+}
+
+// AppSecretEQ applies the EQ predicate on the "app_secret" field.
+func AppSecretEQ(v string) predicate.Xunji {
+	return predicate.Xunji(sql.FieldEQ(FieldAppSecret, v))
+}
+
+// AppSecretNEQ applies the NEQ predicate on the "app_secret" field.
+func AppSecretNEQ(v string) predicate.Xunji {
+	return predicate.Xunji(sql.FieldNEQ(FieldAppSecret, v))
+}
+
+// AppSecretIn applies the In predicate on the "app_secret" field.
+func AppSecretIn(vs ...string) predicate.Xunji {
+	return predicate.Xunji(sql.FieldIn(FieldAppSecret, vs...))
+}
+
+// AppSecretNotIn applies the NotIn predicate on the "app_secret" field.
+func AppSecretNotIn(vs ...string) predicate.Xunji {
+	return predicate.Xunji(sql.FieldNotIn(FieldAppSecret, vs...))
+}
+
+// AppSecretGT applies the GT predicate on the "app_secret" field.
+func AppSecretGT(v string) predicate.Xunji {
+	return predicate.Xunji(sql.FieldGT(FieldAppSecret, v))
+}
+
+// AppSecretGTE applies the GTE predicate on the "app_secret" field.
+func AppSecretGTE(v string) predicate.Xunji {
+	return predicate.Xunji(sql.FieldGTE(FieldAppSecret, v))
+}
+
+// AppSecretLT applies the LT predicate on the "app_secret" field.
+func AppSecretLT(v string) predicate.Xunji {
+	return predicate.Xunji(sql.FieldLT(FieldAppSecret, v))
+}
+
+// AppSecretLTE applies the LTE predicate on the "app_secret" field.
+func AppSecretLTE(v string) predicate.Xunji {
+	return predicate.Xunji(sql.FieldLTE(FieldAppSecret, v))
+}
+
+// AppSecretContains applies the Contains predicate on the "app_secret" field.
+func AppSecretContains(v string) predicate.Xunji {
+	return predicate.Xunji(sql.FieldContains(FieldAppSecret, v))
+}
+
+// AppSecretHasPrefix applies the HasPrefix predicate on the "app_secret" field.
+func AppSecretHasPrefix(v string) predicate.Xunji {
+	return predicate.Xunji(sql.FieldHasPrefix(FieldAppSecret, v))
+}
+
+// AppSecretHasSuffix applies the HasSuffix predicate on the "app_secret" field.
+func AppSecretHasSuffix(v string) predicate.Xunji {
+	return predicate.Xunji(sql.FieldHasSuffix(FieldAppSecret, v))
+}
+
+// AppSecretIsNil applies the IsNil predicate on the "app_secret" field.
+func AppSecretIsNil() predicate.Xunji {
+	return predicate.Xunji(sql.FieldIsNull(FieldAppSecret))
+}
+
+// AppSecretNotNil applies the NotNil predicate on the "app_secret" field.
+func AppSecretNotNil() predicate.Xunji {
+	return predicate.Xunji(sql.FieldNotNull(FieldAppSecret))
+}
+
+// AppSecretEqualFold applies the EqualFold predicate on the "app_secret" field.
+func AppSecretEqualFold(v string) predicate.Xunji {
+	return predicate.Xunji(sql.FieldEqualFold(FieldAppSecret, v))
+}
+
+// AppSecretContainsFold applies the ContainsFold predicate on the "app_secret" field.
+func AppSecretContainsFold(v string) predicate.Xunji {
+	return predicate.Xunji(sql.FieldContainsFold(FieldAppSecret, v))
+}
+
+// TokenEQ applies the EQ predicate on the "token" field.
+func TokenEQ(v string) predicate.Xunji {
+	return predicate.Xunji(sql.FieldEQ(FieldToken, v))
+}
+
+// TokenNEQ applies the NEQ predicate on the "token" field.
+func TokenNEQ(v string) predicate.Xunji {
+	return predicate.Xunji(sql.FieldNEQ(FieldToken, v))
+}
+
+// TokenIn applies the In predicate on the "token" field.
+func TokenIn(vs ...string) predicate.Xunji {
+	return predicate.Xunji(sql.FieldIn(FieldToken, vs...))
+}
+
+// TokenNotIn applies the NotIn predicate on the "token" field.
+func TokenNotIn(vs ...string) predicate.Xunji {
+	return predicate.Xunji(sql.FieldNotIn(FieldToken, vs...))
+}
+
+// TokenGT applies the GT predicate on the "token" field.
+func TokenGT(v string) predicate.Xunji {
+	return predicate.Xunji(sql.FieldGT(FieldToken, v))
+}
+
+// TokenGTE applies the GTE predicate on the "token" field.
+func TokenGTE(v string) predicate.Xunji {
+	return predicate.Xunji(sql.FieldGTE(FieldToken, v))
+}
+
+// TokenLT applies the LT predicate on the "token" field.
+func TokenLT(v string) predicate.Xunji {
+	return predicate.Xunji(sql.FieldLT(FieldToken, v))
+}
+
+// TokenLTE applies the LTE predicate on the "token" field.
+func TokenLTE(v string) predicate.Xunji {
+	return predicate.Xunji(sql.FieldLTE(FieldToken, v))
+}
+
+// TokenContains applies the Contains predicate on the "token" field.
+func TokenContains(v string) predicate.Xunji {
+	return predicate.Xunji(sql.FieldContains(FieldToken, v))
+}
+
+// TokenHasPrefix applies the HasPrefix predicate on the "token" field.
+func TokenHasPrefix(v string) predicate.Xunji {
+	return predicate.Xunji(sql.FieldHasPrefix(FieldToken, v))
+}
+
+// TokenHasSuffix applies the HasSuffix predicate on the "token" field.
+func TokenHasSuffix(v string) predicate.Xunji {
+	return predicate.Xunji(sql.FieldHasSuffix(FieldToken, v))
+}
+
+// TokenIsNil applies the IsNil predicate on the "token" field.
+func TokenIsNil() predicate.Xunji {
+	return predicate.Xunji(sql.FieldIsNull(FieldToken))
+}
+
+// TokenNotNil applies the NotNil predicate on the "token" field.
+func TokenNotNil() predicate.Xunji {
+	return predicate.Xunji(sql.FieldNotNull(FieldToken))
+}
+
+// TokenEqualFold applies the EqualFold predicate on the "token" field.
+func TokenEqualFold(v string) predicate.Xunji {
+	return predicate.Xunji(sql.FieldEqualFold(FieldToken, v))
+}
+
+// TokenContainsFold applies the ContainsFold predicate on the "token" field.
+func TokenContainsFold(v string) predicate.Xunji {
+	return predicate.Xunji(sql.FieldContainsFold(FieldToken, v))
+}
+
+// EncodingKeyEQ applies the EQ predicate on the "encoding_key" field.
+func EncodingKeyEQ(v string) predicate.Xunji {
+	return predicate.Xunji(sql.FieldEQ(FieldEncodingKey, v))
+}
+
+// EncodingKeyNEQ applies the NEQ predicate on the "encoding_key" field.
+func EncodingKeyNEQ(v string) predicate.Xunji {
+	return predicate.Xunji(sql.FieldNEQ(FieldEncodingKey, v))
+}
+
+// EncodingKeyIn applies the In predicate on the "encoding_key" field.
+func EncodingKeyIn(vs ...string) predicate.Xunji {
+	return predicate.Xunji(sql.FieldIn(FieldEncodingKey, vs...))
+}
+
+// EncodingKeyNotIn applies the NotIn predicate on the "encoding_key" field.
+func EncodingKeyNotIn(vs ...string) predicate.Xunji {
+	return predicate.Xunji(sql.FieldNotIn(FieldEncodingKey, vs...))
+}
+
+// EncodingKeyGT applies the GT predicate on the "encoding_key" field.
+func EncodingKeyGT(v string) predicate.Xunji {
+	return predicate.Xunji(sql.FieldGT(FieldEncodingKey, v))
+}
+
+// EncodingKeyGTE applies the GTE predicate on the "encoding_key" field.
+func EncodingKeyGTE(v string) predicate.Xunji {
+	return predicate.Xunji(sql.FieldGTE(FieldEncodingKey, v))
+}
+
+// EncodingKeyLT applies the LT predicate on the "encoding_key" field.
+func EncodingKeyLT(v string) predicate.Xunji {
+	return predicate.Xunji(sql.FieldLT(FieldEncodingKey, v))
+}
+
+// EncodingKeyLTE applies the LTE predicate on the "encoding_key" field.
+func EncodingKeyLTE(v string) predicate.Xunji {
+	return predicate.Xunji(sql.FieldLTE(FieldEncodingKey, v))
+}
+
+// EncodingKeyContains applies the Contains predicate on the "encoding_key" field.
+func EncodingKeyContains(v string) predicate.Xunji {
+	return predicate.Xunji(sql.FieldContains(FieldEncodingKey, v))
+}
+
+// EncodingKeyHasPrefix applies the HasPrefix predicate on the "encoding_key" field.
+func EncodingKeyHasPrefix(v string) predicate.Xunji {
+	return predicate.Xunji(sql.FieldHasPrefix(FieldEncodingKey, v))
+}
+
+// EncodingKeyHasSuffix applies the HasSuffix predicate on the "encoding_key" field.
+func EncodingKeyHasSuffix(v string) predicate.Xunji {
+	return predicate.Xunji(sql.FieldHasSuffix(FieldEncodingKey, v))
+}
+
+// EncodingKeyIsNil applies the IsNil predicate on the "encoding_key" field.
+func EncodingKeyIsNil() predicate.Xunji {
+	return predicate.Xunji(sql.FieldIsNull(FieldEncodingKey))
+}
+
+// EncodingKeyNotNil applies the NotNil predicate on the "encoding_key" field.
+func EncodingKeyNotNil() predicate.Xunji {
+	return predicate.Xunji(sql.FieldNotNull(FieldEncodingKey))
+}
+
+// EncodingKeyEqualFold applies the EqualFold predicate on the "encoding_key" field.
+func EncodingKeyEqualFold(v string) predicate.Xunji {
+	return predicate.Xunji(sql.FieldEqualFold(FieldEncodingKey, v))
+}
+
+// EncodingKeyContainsFold applies the ContainsFold predicate on the "encoding_key" field.
+func EncodingKeyContainsFold(v string) predicate.Xunji {
+	return predicate.Xunji(sql.FieldContainsFold(FieldEncodingKey, v))
+}
+
+// OrganizationIDEQ applies the EQ predicate on the "organization_id" field.
+func OrganizationIDEQ(v uint64) predicate.Xunji {
+	return predicate.Xunji(sql.FieldEQ(FieldOrganizationID, v))
+}
+
+// OrganizationIDNEQ applies the NEQ predicate on the "organization_id" field.
+func OrganizationIDNEQ(v uint64) predicate.Xunji {
+	return predicate.Xunji(sql.FieldNEQ(FieldOrganizationID, v))
+}
+
+// OrganizationIDIn applies the In predicate on the "organization_id" field.
+func OrganizationIDIn(vs ...uint64) predicate.Xunji {
+	return predicate.Xunji(sql.FieldIn(FieldOrganizationID, vs...))
+}
+
+// OrganizationIDNotIn applies the NotIn predicate on the "organization_id" field.
+func OrganizationIDNotIn(vs ...uint64) predicate.Xunji {
+	return predicate.Xunji(sql.FieldNotIn(FieldOrganizationID, vs...))
+}
+
+// OrganizationIDGT applies the GT predicate on the "organization_id" field.
+func OrganizationIDGT(v uint64) predicate.Xunji {
+	return predicate.Xunji(sql.FieldGT(FieldOrganizationID, v))
+}
+
+// OrganizationIDGTE applies the GTE predicate on the "organization_id" field.
+func OrganizationIDGTE(v uint64) predicate.Xunji {
+	return predicate.Xunji(sql.FieldGTE(FieldOrganizationID, v))
+}
+
+// OrganizationIDLT applies the LT predicate on the "organization_id" field.
+func OrganizationIDLT(v uint64) predicate.Xunji {
+	return predicate.Xunji(sql.FieldLT(FieldOrganizationID, v))
+}
+
+// OrganizationIDLTE applies the LTE predicate on the "organization_id" field.
+func OrganizationIDLTE(v uint64) predicate.Xunji {
+	return predicate.Xunji(sql.FieldLTE(FieldOrganizationID, v))
+}
+
+// And groups predicates with the AND operator between them.
+func And(predicates ...predicate.Xunji) predicate.Xunji {
+	return predicate.Xunji(sql.AndPredicates(predicates...))
+}
+
+// Or groups predicates with the OR operator between them.
+func Or(predicates ...predicate.Xunji) predicate.Xunji {
+	return predicate.Xunji(sql.OrPredicates(predicates...))
+}
+
+// Not applies the not operator on the given predicate.
+func Not(p predicate.Xunji) predicate.Xunji {
+	return predicate.Xunji(sql.NotPredicates(p))
+}

+ 134 - 0
ent/xunji/xunji.go

@@ -0,0 +1,134 @@
+// Code generated by ent, DO NOT EDIT.
+
+package xunji
+
+import (
+	"time"
+
+	"entgo.io/ent"
+	"entgo.io/ent/dialect/sql"
+)
+
+const (
+	// Label holds the string label denoting the xunji type in the database.
+	Label = "xunji"
+	// 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"
+	// FieldAppKey holds the string denoting the app_key field in the database.
+	FieldAppKey = "app_key"
+	// FieldAppSecret holds the string denoting the app_secret field in the database.
+	FieldAppSecret = "app_secret"
+	// FieldToken holds the string denoting the token field in the database.
+	FieldToken = "token"
+	// FieldEncodingKey holds the string denoting the encoding_key field in the database.
+	FieldEncodingKey = "encoding_key"
+	// FieldOrganizationID holds the string denoting the organization_id field in the database.
+	FieldOrganizationID = "organization_id"
+	// Table holds the table name of the xunji in the database.
+	Table = "xunji"
+)
+
+// Columns holds all SQL columns for xunji fields.
+var Columns = []string{
+	FieldID,
+	FieldCreatedAt,
+	FieldUpdatedAt,
+	FieldStatus,
+	FieldDeletedAt,
+	FieldAppKey,
+	FieldAppSecret,
+	FieldToken,
+	FieldEncodingKey,
+	FieldOrganizationID,
+}
+
+// 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
+	// OrganizationIDValidator is a validator for the "organization_id" field. It is called by the builders before save.
+	OrganizationIDValidator func(uint64) error
+)
+
+// OrderOption defines the ordering options for the Xunji 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()
+}
+
+// ByAppKey orders the results by the app_key field.
+func ByAppKey(opts ...sql.OrderTermOption) OrderOption {
+	return sql.OrderByField(FieldAppKey, opts...).ToFunc()
+}
+
+// ByAppSecret orders the results by the app_secret field.
+func ByAppSecret(opts ...sql.OrderTermOption) OrderOption {
+	return sql.OrderByField(FieldAppSecret, opts...).ToFunc()
+}
+
+// ByToken orders the results by the token field.
+func ByToken(opts ...sql.OrderTermOption) OrderOption {
+	return sql.OrderByField(FieldToken, opts...).ToFunc()
+}
+
+// ByEncodingKey orders the results by the encoding_key field.
+func ByEncodingKey(opts ...sql.OrderTermOption) OrderOption {
+	return sql.OrderByField(FieldEncodingKey, opts...).ToFunc()
+}
+
+// ByOrganizationID orders the results by the organization_id field.
+func ByOrganizationID(opts ...sql.OrderTermOption) OrderOption {
+	return sql.OrderByField(FieldOrganizationID, opts...).ToFunc()
+}

+ 1113 - 0
ent/xunji_create.go

@@ -0,0 +1,1113 @@
+// Code generated by ent, DO NOT EDIT.
+
+package ent
+
+import (
+	"context"
+	"errors"
+	"fmt"
+	"time"
+	"wechat-api/ent/xunji"
+
+	"entgo.io/ent/dialect/sql"
+	"entgo.io/ent/dialect/sql/sqlgraph"
+	"entgo.io/ent/schema/field"
+)
+
+// XunjiCreate is the builder for creating a Xunji entity.
+type XunjiCreate struct {
+	config
+	mutation *XunjiMutation
+	hooks    []Hook
+	conflict []sql.ConflictOption
+}
+
+// SetCreatedAt sets the "created_at" field.
+func (xc *XunjiCreate) SetCreatedAt(t time.Time) *XunjiCreate {
+	xc.mutation.SetCreatedAt(t)
+	return xc
+}
+
+// SetNillableCreatedAt sets the "created_at" field if the given value is not nil.
+func (xc *XunjiCreate) SetNillableCreatedAt(t *time.Time) *XunjiCreate {
+	if t != nil {
+		xc.SetCreatedAt(*t)
+	}
+	return xc
+}
+
+// SetUpdatedAt sets the "updated_at" field.
+func (xc *XunjiCreate) SetUpdatedAt(t time.Time) *XunjiCreate {
+	xc.mutation.SetUpdatedAt(t)
+	return xc
+}
+
+// SetNillableUpdatedAt sets the "updated_at" field if the given value is not nil.
+func (xc *XunjiCreate) SetNillableUpdatedAt(t *time.Time) *XunjiCreate {
+	if t != nil {
+		xc.SetUpdatedAt(*t)
+	}
+	return xc
+}
+
+// SetStatus sets the "status" field.
+func (xc *XunjiCreate) SetStatus(u uint8) *XunjiCreate {
+	xc.mutation.SetStatus(u)
+	return xc
+}
+
+// SetNillableStatus sets the "status" field if the given value is not nil.
+func (xc *XunjiCreate) SetNillableStatus(u *uint8) *XunjiCreate {
+	if u != nil {
+		xc.SetStatus(*u)
+	}
+	return xc
+}
+
+// SetDeletedAt sets the "deleted_at" field.
+func (xc *XunjiCreate) SetDeletedAt(t time.Time) *XunjiCreate {
+	xc.mutation.SetDeletedAt(t)
+	return xc
+}
+
+// SetNillableDeletedAt sets the "deleted_at" field if the given value is not nil.
+func (xc *XunjiCreate) SetNillableDeletedAt(t *time.Time) *XunjiCreate {
+	if t != nil {
+		xc.SetDeletedAt(*t)
+	}
+	return xc
+}
+
+// SetAppKey sets the "app_key" field.
+func (xc *XunjiCreate) SetAppKey(s string) *XunjiCreate {
+	xc.mutation.SetAppKey(s)
+	return xc
+}
+
+// SetNillableAppKey sets the "app_key" field if the given value is not nil.
+func (xc *XunjiCreate) SetNillableAppKey(s *string) *XunjiCreate {
+	if s != nil {
+		xc.SetAppKey(*s)
+	}
+	return xc
+}
+
+// SetAppSecret sets the "app_secret" field.
+func (xc *XunjiCreate) SetAppSecret(s string) *XunjiCreate {
+	xc.mutation.SetAppSecret(s)
+	return xc
+}
+
+// SetNillableAppSecret sets the "app_secret" field if the given value is not nil.
+func (xc *XunjiCreate) SetNillableAppSecret(s *string) *XunjiCreate {
+	if s != nil {
+		xc.SetAppSecret(*s)
+	}
+	return xc
+}
+
+// SetToken sets the "token" field.
+func (xc *XunjiCreate) SetToken(s string) *XunjiCreate {
+	xc.mutation.SetToken(s)
+	return xc
+}
+
+// SetNillableToken sets the "token" field if the given value is not nil.
+func (xc *XunjiCreate) SetNillableToken(s *string) *XunjiCreate {
+	if s != nil {
+		xc.SetToken(*s)
+	}
+	return xc
+}
+
+// SetEncodingKey sets the "encoding_key" field.
+func (xc *XunjiCreate) SetEncodingKey(s string) *XunjiCreate {
+	xc.mutation.SetEncodingKey(s)
+	return xc
+}
+
+// SetNillableEncodingKey sets the "encoding_key" field if the given value is not nil.
+func (xc *XunjiCreate) SetNillableEncodingKey(s *string) *XunjiCreate {
+	if s != nil {
+		xc.SetEncodingKey(*s)
+	}
+	return xc
+}
+
+// SetOrganizationID sets the "organization_id" field.
+func (xc *XunjiCreate) SetOrganizationID(u uint64) *XunjiCreate {
+	xc.mutation.SetOrganizationID(u)
+	return xc
+}
+
+// SetID sets the "id" field.
+func (xc *XunjiCreate) SetID(u uint64) *XunjiCreate {
+	xc.mutation.SetID(u)
+	return xc
+}
+
+// Mutation returns the XunjiMutation object of the builder.
+func (xc *XunjiCreate) Mutation() *XunjiMutation {
+	return xc.mutation
+}
+
+// Save creates the Xunji in the database.
+func (xc *XunjiCreate) Save(ctx context.Context) (*Xunji, error) {
+	if err := xc.defaults(); err != nil {
+		return nil, err
+	}
+	return withHooks(ctx, xc.sqlSave, xc.mutation, xc.hooks)
+}
+
+// SaveX calls Save and panics if Save returns an error.
+func (xc *XunjiCreate) SaveX(ctx context.Context) *Xunji {
+	v, err := xc.Save(ctx)
+	if err != nil {
+		panic(err)
+	}
+	return v
+}
+
+// Exec executes the query.
+func (xc *XunjiCreate) Exec(ctx context.Context) error {
+	_, err := xc.Save(ctx)
+	return err
+}
+
+// ExecX is like Exec, but panics if an error occurs.
+func (xc *XunjiCreate) ExecX(ctx context.Context) {
+	if err := xc.Exec(ctx); err != nil {
+		panic(err)
+	}
+}
+
+// defaults sets the default values of the builder before save.
+func (xc *XunjiCreate) defaults() error {
+	if _, ok := xc.mutation.CreatedAt(); !ok {
+		if xunji.DefaultCreatedAt == nil {
+			return fmt.Errorf("ent: uninitialized xunji.DefaultCreatedAt (forgotten import ent/runtime?)")
+		}
+		v := xunji.DefaultCreatedAt()
+		xc.mutation.SetCreatedAt(v)
+	}
+	if _, ok := xc.mutation.UpdatedAt(); !ok {
+		if xunji.DefaultUpdatedAt == nil {
+			return fmt.Errorf("ent: uninitialized xunji.DefaultUpdatedAt (forgotten import ent/runtime?)")
+		}
+		v := xunji.DefaultUpdatedAt()
+		xc.mutation.SetUpdatedAt(v)
+	}
+	if _, ok := xc.mutation.Status(); !ok {
+		v := xunji.DefaultStatus
+		xc.mutation.SetStatus(v)
+	}
+	return nil
+}
+
+// check runs all checks and user-defined validators on the builder.
+func (xc *XunjiCreate) check() error {
+	if _, ok := xc.mutation.CreatedAt(); !ok {
+		return &ValidationError{Name: "created_at", err: errors.New(`ent: missing required field "Xunji.created_at"`)}
+	}
+	if _, ok := xc.mutation.UpdatedAt(); !ok {
+		return &ValidationError{Name: "updated_at", err: errors.New(`ent: missing required field "Xunji.updated_at"`)}
+	}
+	if _, ok := xc.mutation.OrganizationID(); !ok {
+		return &ValidationError{Name: "organization_id", err: errors.New(`ent: missing required field "Xunji.organization_id"`)}
+	}
+	if v, ok := xc.mutation.OrganizationID(); ok {
+		if err := xunji.OrganizationIDValidator(v); err != nil {
+			return &ValidationError{Name: "organization_id", err: fmt.Errorf(`ent: validator failed for field "Xunji.organization_id": %w`, err)}
+		}
+	}
+	return nil
+}
+
+func (xc *XunjiCreate) sqlSave(ctx context.Context) (*Xunji, error) {
+	if err := xc.check(); err != nil {
+		return nil, err
+	}
+	_node, _spec := xc.createSpec()
+	if err := sqlgraph.CreateNode(ctx, xc.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)
+	}
+	xc.mutation.id = &_node.ID
+	xc.mutation.done = true
+	return _node, nil
+}
+
+func (xc *XunjiCreate) createSpec() (*Xunji, *sqlgraph.CreateSpec) {
+	var (
+		_node = &Xunji{config: xc.config}
+		_spec = sqlgraph.NewCreateSpec(xunji.Table, sqlgraph.NewFieldSpec(xunji.FieldID, field.TypeUint64))
+	)
+	_spec.OnConflict = xc.conflict
+	if id, ok := xc.mutation.ID(); ok {
+		_node.ID = id
+		_spec.ID.Value = id
+	}
+	if value, ok := xc.mutation.CreatedAt(); ok {
+		_spec.SetField(xunji.FieldCreatedAt, field.TypeTime, value)
+		_node.CreatedAt = value
+	}
+	if value, ok := xc.mutation.UpdatedAt(); ok {
+		_spec.SetField(xunji.FieldUpdatedAt, field.TypeTime, value)
+		_node.UpdatedAt = value
+	}
+	if value, ok := xc.mutation.Status(); ok {
+		_spec.SetField(xunji.FieldStatus, field.TypeUint8, value)
+		_node.Status = value
+	}
+	if value, ok := xc.mutation.DeletedAt(); ok {
+		_spec.SetField(xunji.FieldDeletedAt, field.TypeTime, value)
+		_node.DeletedAt = value
+	}
+	if value, ok := xc.mutation.AppKey(); ok {
+		_spec.SetField(xunji.FieldAppKey, field.TypeString, value)
+		_node.AppKey = value
+	}
+	if value, ok := xc.mutation.AppSecret(); ok {
+		_spec.SetField(xunji.FieldAppSecret, field.TypeString, value)
+		_node.AppSecret = value
+	}
+	if value, ok := xc.mutation.Token(); ok {
+		_spec.SetField(xunji.FieldToken, field.TypeString, value)
+		_node.Token = value
+	}
+	if value, ok := xc.mutation.EncodingKey(); ok {
+		_spec.SetField(xunji.FieldEncodingKey, field.TypeString, value)
+		_node.EncodingKey = value
+	}
+	if value, ok := xc.mutation.OrganizationID(); ok {
+		_spec.SetField(xunji.FieldOrganizationID, field.TypeUint64, value)
+		_node.OrganizationID = value
+	}
+	return _node, _spec
+}
+
+// OnConflict allows configuring the `ON CONFLICT` / `ON DUPLICATE KEY` clause
+// of the `INSERT` statement. For example:
+//
+//	client.Xunji.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.XunjiUpsert) {
+//			SetCreatedAt(v+v).
+//		}).
+//		Exec(ctx)
+func (xc *XunjiCreate) OnConflict(opts ...sql.ConflictOption) *XunjiUpsertOne {
+	xc.conflict = opts
+	return &XunjiUpsertOne{
+		create: xc,
+	}
+}
+
+// OnConflictColumns calls `OnConflict` and configures the columns
+// as conflict target. Using this option is equivalent to using:
+//
+//	client.Xunji.Create().
+//		OnConflict(sql.ConflictColumns(columns...)).
+//		Exec(ctx)
+func (xc *XunjiCreate) OnConflictColumns(columns ...string) *XunjiUpsertOne {
+	xc.conflict = append(xc.conflict, sql.ConflictColumns(columns...))
+	return &XunjiUpsertOne{
+		create: xc,
+	}
+}
+
+type (
+	// XunjiUpsertOne is the builder for "upsert"-ing
+	//  one Xunji node.
+	XunjiUpsertOne struct {
+		create *XunjiCreate
+	}
+
+	// XunjiUpsert is the "OnConflict" setter.
+	XunjiUpsert struct {
+		*sql.UpdateSet
+	}
+)
+
+// SetUpdatedAt sets the "updated_at" field.
+func (u *XunjiUpsert) SetUpdatedAt(v time.Time) *XunjiUpsert {
+	u.Set(xunji.FieldUpdatedAt, v)
+	return u
+}
+
+// UpdateUpdatedAt sets the "updated_at" field to the value that was provided on create.
+func (u *XunjiUpsert) UpdateUpdatedAt() *XunjiUpsert {
+	u.SetExcluded(xunji.FieldUpdatedAt)
+	return u
+}
+
+// SetStatus sets the "status" field.
+func (u *XunjiUpsert) SetStatus(v uint8) *XunjiUpsert {
+	u.Set(xunji.FieldStatus, v)
+	return u
+}
+
+// UpdateStatus sets the "status" field to the value that was provided on create.
+func (u *XunjiUpsert) UpdateStatus() *XunjiUpsert {
+	u.SetExcluded(xunji.FieldStatus)
+	return u
+}
+
+// AddStatus adds v to the "status" field.
+func (u *XunjiUpsert) AddStatus(v uint8) *XunjiUpsert {
+	u.Add(xunji.FieldStatus, v)
+	return u
+}
+
+// ClearStatus clears the value of the "status" field.
+func (u *XunjiUpsert) ClearStatus() *XunjiUpsert {
+	u.SetNull(xunji.FieldStatus)
+	return u
+}
+
+// SetDeletedAt sets the "deleted_at" field.
+func (u *XunjiUpsert) SetDeletedAt(v time.Time) *XunjiUpsert {
+	u.Set(xunji.FieldDeletedAt, v)
+	return u
+}
+
+// UpdateDeletedAt sets the "deleted_at" field to the value that was provided on create.
+func (u *XunjiUpsert) UpdateDeletedAt() *XunjiUpsert {
+	u.SetExcluded(xunji.FieldDeletedAt)
+	return u
+}
+
+// ClearDeletedAt clears the value of the "deleted_at" field.
+func (u *XunjiUpsert) ClearDeletedAt() *XunjiUpsert {
+	u.SetNull(xunji.FieldDeletedAt)
+	return u
+}
+
+// SetAppKey sets the "app_key" field.
+func (u *XunjiUpsert) SetAppKey(v string) *XunjiUpsert {
+	u.Set(xunji.FieldAppKey, v)
+	return u
+}
+
+// UpdateAppKey sets the "app_key" field to the value that was provided on create.
+func (u *XunjiUpsert) UpdateAppKey() *XunjiUpsert {
+	u.SetExcluded(xunji.FieldAppKey)
+	return u
+}
+
+// ClearAppKey clears the value of the "app_key" field.
+func (u *XunjiUpsert) ClearAppKey() *XunjiUpsert {
+	u.SetNull(xunji.FieldAppKey)
+	return u
+}
+
+// SetAppSecret sets the "app_secret" field.
+func (u *XunjiUpsert) SetAppSecret(v string) *XunjiUpsert {
+	u.Set(xunji.FieldAppSecret, v)
+	return u
+}
+
+// UpdateAppSecret sets the "app_secret" field to the value that was provided on create.
+func (u *XunjiUpsert) UpdateAppSecret() *XunjiUpsert {
+	u.SetExcluded(xunji.FieldAppSecret)
+	return u
+}
+
+// ClearAppSecret clears the value of the "app_secret" field.
+func (u *XunjiUpsert) ClearAppSecret() *XunjiUpsert {
+	u.SetNull(xunji.FieldAppSecret)
+	return u
+}
+
+// SetToken sets the "token" field.
+func (u *XunjiUpsert) SetToken(v string) *XunjiUpsert {
+	u.Set(xunji.FieldToken, v)
+	return u
+}
+
+// UpdateToken sets the "token" field to the value that was provided on create.
+func (u *XunjiUpsert) UpdateToken() *XunjiUpsert {
+	u.SetExcluded(xunji.FieldToken)
+	return u
+}
+
+// ClearToken clears the value of the "token" field.
+func (u *XunjiUpsert) ClearToken() *XunjiUpsert {
+	u.SetNull(xunji.FieldToken)
+	return u
+}
+
+// SetEncodingKey sets the "encoding_key" field.
+func (u *XunjiUpsert) SetEncodingKey(v string) *XunjiUpsert {
+	u.Set(xunji.FieldEncodingKey, v)
+	return u
+}
+
+// UpdateEncodingKey sets the "encoding_key" field to the value that was provided on create.
+func (u *XunjiUpsert) UpdateEncodingKey() *XunjiUpsert {
+	u.SetExcluded(xunji.FieldEncodingKey)
+	return u
+}
+
+// ClearEncodingKey clears the value of the "encoding_key" field.
+func (u *XunjiUpsert) ClearEncodingKey() *XunjiUpsert {
+	u.SetNull(xunji.FieldEncodingKey)
+	return u
+}
+
+// SetOrganizationID sets the "organization_id" field.
+func (u *XunjiUpsert) SetOrganizationID(v uint64) *XunjiUpsert {
+	u.Set(xunji.FieldOrganizationID, v)
+	return u
+}
+
+// UpdateOrganizationID sets the "organization_id" field to the value that was provided on create.
+func (u *XunjiUpsert) UpdateOrganizationID() *XunjiUpsert {
+	u.SetExcluded(xunji.FieldOrganizationID)
+	return u
+}
+
+// AddOrganizationID adds v to the "organization_id" field.
+func (u *XunjiUpsert) AddOrganizationID(v uint64) *XunjiUpsert {
+	u.Add(xunji.FieldOrganizationID, v)
+	return u
+}
+
+// UpdateNewValues updates the mutable fields using the new values that were set on create except the ID field.
+// Using this option is equivalent to using:
+//
+//	client.Xunji.Create().
+//		OnConflict(
+//			sql.ResolveWithNewValues(),
+//			sql.ResolveWith(func(u *sql.UpdateSet) {
+//				u.SetIgnore(xunji.FieldID)
+//			}),
+//		).
+//		Exec(ctx)
+func (u *XunjiUpsertOne) UpdateNewValues() *XunjiUpsertOne {
+	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(xunji.FieldID)
+		}
+		if _, exists := u.create.mutation.CreatedAt(); exists {
+			s.SetIgnore(xunji.FieldCreatedAt)
+		}
+	}))
+	return u
+}
+
+// Ignore sets each column to itself in case of conflict.
+// Using this option is equivalent to using:
+//
+//	client.Xunji.Create().
+//	    OnConflict(sql.ResolveWithIgnore()).
+//	    Exec(ctx)
+func (u *XunjiUpsertOne) Ignore() *XunjiUpsertOne {
+	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 *XunjiUpsertOne) DoNothing() *XunjiUpsertOne {
+	u.create.conflict = append(u.create.conflict, sql.DoNothing())
+	return u
+}
+
+// Update allows overriding fields `UPDATE` values. See the XunjiCreate.OnConflict
+// documentation for more info.
+func (u *XunjiUpsertOne) Update(set func(*XunjiUpsert)) *XunjiUpsertOne {
+	u.create.conflict = append(u.create.conflict, sql.ResolveWith(func(update *sql.UpdateSet) {
+		set(&XunjiUpsert{UpdateSet: update})
+	}))
+	return u
+}
+
+// SetUpdatedAt sets the "updated_at" field.
+func (u *XunjiUpsertOne) SetUpdatedAt(v time.Time) *XunjiUpsertOne {
+	return u.Update(func(s *XunjiUpsert) {
+		s.SetUpdatedAt(v)
+	})
+}
+
+// UpdateUpdatedAt sets the "updated_at" field to the value that was provided on create.
+func (u *XunjiUpsertOne) UpdateUpdatedAt() *XunjiUpsertOne {
+	return u.Update(func(s *XunjiUpsert) {
+		s.UpdateUpdatedAt()
+	})
+}
+
+// SetStatus sets the "status" field.
+func (u *XunjiUpsertOne) SetStatus(v uint8) *XunjiUpsertOne {
+	return u.Update(func(s *XunjiUpsert) {
+		s.SetStatus(v)
+	})
+}
+
+// AddStatus adds v to the "status" field.
+func (u *XunjiUpsertOne) AddStatus(v uint8) *XunjiUpsertOne {
+	return u.Update(func(s *XunjiUpsert) {
+		s.AddStatus(v)
+	})
+}
+
+// UpdateStatus sets the "status" field to the value that was provided on create.
+func (u *XunjiUpsertOne) UpdateStatus() *XunjiUpsertOne {
+	return u.Update(func(s *XunjiUpsert) {
+		s.UpdateStatus()
+	})
+}
+
+// ClearStatus clears the value of the "status" field.
+func (u *XunjiUpsertOne) ClearStatus() *XunjiUpsertOne {
+	return u.Update(func(s *XunjiUpsert) {
+		s.ClearStatus()
+	})
+}
+
+// SetDeletedAt sets the "deleted_at" field.
+func (u *XunjiUpsertOne) SetDeletedAt(v time.Time) *XunjiUpsertOne {
+	return u.Update(func(s *XunjiUpsert) {
+		s.SetDeletedAt(v)
+	})
+}
+
+// UpdateDeletedAt sets the "deleted_at" field to the value that was provided on create.
+func (u *XunjiUpsertOne) UpdateDeletedAt() *XunjiUpsertOne {
+	return u.Update(func(s *XunjiUpsert) {
+		s.UpdateDeletedAt()
+	})
+}
+
+// ClearDeletedAt clears the value of the "deleted_at" field.
+func (u *XunjiUpsertOne) ClearDeletedAt() *XunjiUpsertOne {
+	return u.Update(func(s *XunjiUpsert) {
+		s.ClearDeletedAt()
+	})
+}
+
+// SetAppKey sets the "app_key" field.
+func (u *XunjiUpsertOne) SetAppKey(v string) *XunjiUpsertOne {
+	return u.Update(func(s *XunjiUpsert) {
+		s.SetAppKey(v)
+	})
+}
+
+// UpdateAppKey sets the "app_key" field to the value that was provided on create.
+func (u *XunjiUpsertOne) UpdateAppKey() *XunjiUpsertOne {
+	return u.Update(func(s *XunjiUpsert) {
+		s.UpdateAppKey()
+	})
+}
+
+// ClearAppKey clears the value of the "app_key" field.
+func (u *XunjiUpsertOne) ClearAppKey() *XunjiUpsertOne {
+	return u.Update(func(s *XunjiUpsert) {
+		s.ClearAppKey()
+	})
+}
+
+// SetAppSecret sets the "app_secret" field.
+func (u *XunjiUpsertOne) SetAppSecret(v string) *XunjiUpsertOne {
+	return u.Update(func(s *XunjiUpsert) {
+		s.SetAppSecret(v)
+	})
+}
+
+// UpdateAppSecret sets the "app_secret" field to the value that was provided on create.
+func (u *XunjiUpsertOne) UpdateAppSecret() *XunjiUpsertOne {
+	return u.Update(func(s *XunjiUpsert) {
+		s.UpdateAppSecret()
+	})
+}
+
+// ClearAppSecret clears the value of the "app_secret" field.
+func (u *XunjiUpsertOne) ClearAppSecret() *XunjiUpsertOne {
+	return u.Update(func(s *XunjiUpsert) {
+		s.ClearAppSecret()
+	})
+}
+
+// SetToken sets the "token" field.
+func (u *XunjiUpsertOne) SetToken(v string) *XunjiUpsertOne {
+	return u.Update(func(s *XunjiUpsert) {
+		s.SetToken(v)
+	})
+}
+
+// UpdateToken sets the "token" field to the value that was provided on create.
+func (u *XunjiUpsertOne) UpdateToken() *XunjiUpsertOne {
+	return u.Update(func(s *XunjiUpsert) {
+		s.UpdateToken()
+	})
+}
+
+// ClearToken clears the value of the "token" field.
+func (u *XunjiUpsertOne) ClearToken() *XunjiUpsertOne {
+	return u.Update(func(s *XunjiUpsert) {
+		s.ClearToken()
+	})
+}
+
+// SetEncodingKey sets the "encoding_key" field.
+func (u *XunjiUpsertOne) SetEncodingKey(v string) *XunjiUpsertOne {
+	return u.Update(func(s *XunjiUpsert) {
+		s.SetEncodingKey(v)
+	})
+}
+
+// UpdateEncodingKey sets the "encoding_key" field to the value that was provided on create.
+func (u *XunjiUpsertOne) UpdateEncodingKey() *XunjiUpsertOne {
+	return u.Update(func(s *XunjiUpsert) {
+		s.UpdateEncodingKey()
+	})
+}
+
+// ClearEncodingKey clears the value of the "encoding_key" field.
+func (u *XunjiUpsertOne) ClearEncodingKey() *XunjiUpsertOne {
+	return u.Update(func(s *XunjiUpsert) {
+		s.ClearEncodingKey()
+	})
+}
+
+// SetOrganizationID sets the "organization_id" field.
+func (u *XunjiUpsertOne) SetOrganizationID(v uint64) *XunjiUpsertOne {
+	return u.Update(func(s *XunjiUpsert) {
+		s.SetOrganizationID(v)
+	})
+}
+
+// AddOrganizationID adds v to the "organization_id" field.
+func (u *XunjiUpsertOne) AddOrganizationID(v uint64) *XunjiUpsertOne {
+	return u.Update(func(s *XunjiUpsert) {
+		s.AddOrganizationID(v)
+	})
+}
+
+// UpdateOrganizationID sets the "organization_id" field to the value that was provided on create.
+func (u *XunjiUpsertOne) UpdateOrganizationID() *XunjiUpsertOne {
+	return u.Update(func(s *XunjiUpsert) {
+		s.UpdateOrganizationID()
+	})
+}
+
+// Exec executes the query.
+func (u *XunjiUpsertOne) Exec(ctx context.Context) error {
+	if len(u.create.conflict) == 0 {
+		return errors.New("ent: missing options for XunjiCreate.OnConflict")
+	}
+	return u.create.Exec(ctx)
+}
+
+// ExecX is like Exec, but panics if an error occurs.
+func (u *XunjiUpsertOne) 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 *XunjiUpsertOne) 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 *XunjiUpsertOne) IDX(ctx context.Context) uint64 {
+	id, err := u.ID(ctx)
+	if err != nil {
+		panic(err)
+	}
+	return id
+}
+
+// XunjiCreateBulk is the builder for creating many Xunji entities in bulk.
+type XunjiCreateBulk struct {
+	config
+	err      error
+	builders []*XunjiCreate
+	conflict []sql.ConflictOption
+}
+
+// Save creates the Xunji entities in the database.
+func (xcb *XunjiCreateBulk) Save(ctx context.Context) ([]*Xunji, error) {
+	if xcb.err != nil {
+		return nil, xcb.err
+	}
+	specs := make([]*sqlgraph.CreateSpec, len(xcb.builders))
+	nodes := make([]*Xunji, len(xcb.builders))
+	mutators := make([]Mutator, len(xcb.builders))
+	for i := range xcb.builders {
+		func(i int, root context.Context) {
+			builder := xcb.builders[i]
+			builder.defaults()
+			var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) {
+				mutation, ok := m.(*XunjiMutation)
+				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, xcb.builders[i+1].mutation)
+				} else {
+					spec := &sqlgraph.BatchCreateSpec{Nodes: specs}
+					spec.OnConflict = xcb.conflict
+					// Invoke the actual operation on the latest mutation in the chain.
+					if err = sqlgraph.BatchCreate(ctx, xcb.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, xcb.builders[0].mutation); err != nil {
+			return nil, err
+		}
+	}
+	return nodes, nil
+}
+
+// SaveX is like Save, but panics if an error occurs.
+func (xcb *XunjiCreateBulk) SaveX(ctx context.Context) []*Xunji {
+	v, err := xcb.Save(ctx)
+	if err != nil {
+		panic(err)
+	}
+	return v
+}
+
+// Exec executes the query.
+func (xcb *XunjiCreateBulk) Exec(ctx context.Context) error {
+	_, err := xcb.Save(ctx)
+	return err
+}
+
+// ExecX is like Exec, but panics if an error occurs.
+func (xcb *XunjiCreateBulk) ExecX(ctx context.Context) {
+	if err := xcb.Exec(ctx); err != nil {
+		panic(err)
+	}
+}
+
+// OnConflict allows configuring the `ON CONFLICT` / `ON DUPLICATE KEY` clause
+// of the `INSERT` statement. For example:
+//
+//	client.Xunji.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.XunjiUpsert) {
+//			SetCreatedAt(v+v).
+//		}).
+//		Exec(ctx)
+func (xcb *XunjiCreateBulk) OnConflict(opts ...sql.ConflictOption) *XunjiUpsertBulk {
+	xcb.conflict = opts
+	return &XunjiUpsertBulk{
+		create: xcb,
+	}
+}
+
+// OnConflictColumns calls `OnConflict` and configures the columns
+// as conflict target. Using this option is equivalent to using:
+//
+//	client.Xunji.Create().
+//		OnConflict(sql.ConflictColumns(columns...)).
+//		Exec(ctx)
+func (xcb *XunjiCreateBulk) OnConflictColumns(columns ...string) *XunjiUpsertBulk {
+	xcb.conflict = append(xcb.conflict, sql.ConflictColumns(columns...))
+	return &XunjiUpsertBulk{
+		create: xcb,
+	}
+}
+
+// XunjiUpsertBulk is the builder for "upsert"-ing
+// a bulk of Xunji nodes.
+type XunjiUpsertBulk struct {
+	create *XunjiCreateBulk
+}
+
+// UpdateNewValues updates the mutable fields using the new values that
+// were set on create. Using this option is equivalent to using:
+//
+//	client.Xunji.Create().
+//		OnConflict(
+//			sql.ResolveWithNewValues(),
+//			sql.ResolveWith(func(u *sql.UpdateSet) {
+//				u.SetIgnore(xunji.FieldID)
+//			}),
+//		).
+//		Exec(ctx)
+func (u *XunjiUpsertBulk) UpdateNewValues() *XunjiUpsertBulk {
+	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(xunji.FieldID)
+			}
+			if _, exists := b.mutation.CreatedAt(); exists {
+				s.SetIgnore(xunji.FieldCreatedAt)
+			}
+		}
+	}))
+	return u
+}
+
+// Ignore sets each column to itself in case of conflict.
+// Using this option is equivalent to using:
+//
+//	client.Xunji.Create().
+//		OnConflict(sql.ResolveWithIgnore()).
+//		Exec(ctx)
+func (u *XunjiUpsertBulk) Ignore() *XunjiUpsertBulk {
+	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 *XunjiUpsertBulk) DoNothing() *XunjiUpsertBulk {
+	u.create.conflict = append(u.create.conflict, sql.DoNothing())
+	return u
+}
+
+// Update allows overriding fields `UPDATE` values. See the XunjiCreateBulk.OnConflict
+// documentation for more info.
+func (u *XunjiUpsertBulk) Update(set func(*XunjiUpsert)) *XunjiUpsertBulk {
+	u.create.conflict = append(u.create.conflict, sql.ResolveWith(func(update *sql.UpdateSet) {
+		set(&XunjiUpsert{UpdateSet: update})
+	}))
+	return u
+}
+
+// SetUpdatedAt sets the "updated_at" field.
+func (u *XunjiUpsertBulk) SetUpdatedAt(v time.Time) *XunjiUpsertBulk {
+	return u.Update(func(s *XunjiUpsert) {
+		s.SetUpdatedAt(v)
+	})
+}
+
+// UpdateUpdatedAt sets the "updated_at" field to the value that was provided on create.
+func (u *XunjiUpsertBulk) UpdateUpdatedAt() *XunjiUpsertBulk {
+	return u.Update(func(s *XunjiUpsert) {
+		s.UpdateUpdatedAt()
+	})
+}
+
+// SetStatus sets the "status" field.
+func (u *XunjiUpsertBulk) SetStatus(v uint8) *XunjiUpsertBulk {
+	return u.Update(func(s *XunjiUpsert) {
+		s.SetStatus(v)
+	})
+}
+
+// AddStatus adds v to the "status" field.
+func (u *XunjiUpsertBulk) AddStatus(v uint8) *XunjiUpsertBulk {
+	return u.Update(func(s *XunjiUpsert) {
+		s.AddStatus(v)
+	})
+}
+
+// UpdateStatus sets the "status" field to the value that was provided on create.
+func (u *XunjiUpsertBulk) UpdateStatus() *XunjiUpsertBulk {
+	return u.Update(func(s *XunjiUpsert) {
+		s.UpdateStatus()
+	})
+}
+
+// ClearStatus clears the value of the "status" field.
+func (u *XunjiUpsertBulk) ClearStatus() *XunjiUpsertBulk {
+	return u.Update(func(s *XunjiUpsert) {
+		s.ClearStatus()
+	})
+}
+
+// SetDeletedAt sets the "deleted_at" field.
+func (u *XunjiUpsertBulk) SetDeletedAt(v time.Time) *XunjiUpsertBulk {
+	return u.Update(func(s *XunjiUpsert) {
+		s.SetDeletedAt(v)
+	})
+}
+
+// UpdateDeletedAt sets the "deleted_at" field to the value that was provided on create.
+func (u *XunjiUpsertBulk) UpdateDeletedAt() *XunjiUpsertBulk {
+	return u.Update(func(s *XunjiUpsert) {
+		s.UpdateDeletedAt()
+	})
+}
+
+// ClearDeletedAt clears the value of the "deleted_at" field.
+func (u *XunjiUpsertBulk) ClearDeletedAt() *XunjiUpsertBulk {
+	return u.Update(func(s *XunjiUpsert) {
+		s.ClearDeletedAt()
+	})
+}
+
+// SetAppKey sets the "app_key" field.
+func (u *XunjiUpsertBulk) SetAppKey(v string) *XunjiUpsertBulk {
+	return u.Update(func(s *XunjiUpsert) {
+		s.SetAppKey(v)
+	})
+}
+
+// UpdateAppKey sets the "app_key" field to the value that was provided on create.
+func (u *XunjiUpsertBulk) UpdateAppKey() *XunjiUpsertBulk {
+	return u.Update(func(s *XunjiUpsert) {
+		s.UpdateAppKey()
+	})
+}
+
+// ClearAppKey clears the value of the "app_key" field.
+func (u *XunjiUpsertBulk) ClearAppKey() *XunjiUpsertBulk {
+	return u.Update(func(s *XunjiUpsert) {
+		s.ClearAppKey()
+	})
+}
+
+// SetAppSecret sets the "app_secret" field.
+func (u *XunjiUpsertBulk) SetAppSecret(v string) *XunjiUpsertBulk {
+	return u.Update(func(s *XunjiUpsert) {
+		s.SetAppSecret(v)
+	})
+}
+
+// UpdateAppSecret sets the "app_secret" field to the value that was provided on create.
+func (u *XunjiUpsertBulk) UpdateAppSecret() *XunjiUpsertBulk {
+	return u.Update(func(s *XunjiUpsert) {
+		s.UpdateAppSecret()
+	})
+}
+
+// ClearAppSecret clears the value of the "app_secret" field.
+func (u *XunjiUpsertBulk) ClearAppSecret() *XunjiUpsertBulk {
+	return u.Update(func(s *XunjiUpsert) {
+		s.ClearAppSecret()
+	})
+}
+
+// SetToken sets the "token" field.
+func (u *XunjiUpsertBulk) SetToken(v string) *XunjiUpsertBulk {
+	return u.Update(func(s *XunjiUpsert) {
+		s.SetToken(v)
+	})
+}
+
+// UpdateToken sets the "token" field to the value that was provided on create.
+func (u *XunjiUpsertBulk) UpdateToken() *XunjiUpsertBulk {
+	return u.Update(func(s *XunjiUpsert) {
+		s.UpdateToken()
+	})
+}
+
+// ClearToken clears the value of the "token" field.
+func (u *XunjiUpsertBulk) ClearToken() *XunjiUpsertBulk {
+	return u.Update(func(s *XunjiUpsert) {
+		s.ClearToken()
+	})
+}
+
+// SetEncodingKey sets the "encoding_key" field.
+func (u *XunjiUpsertBulk) SetEncodingKey(v string) *XunjiUpsertBulk {
+	return u.Update(func(s *XunjiUpsert) {
+		s.SetEncodingKey(v)
+	})
+}
+
+// UpdateEncodingKey sets the "encoding_key" field to the value that was provided on create.
+func (u *XunjiUpsertBulk) UpdateEncodingKey() *XunjiUpsertBulk {
+	return u.Update(func(s *XunjiUpsert) {
+		s.UpdateEncodingKey()
+	})
+}
+
+// ClearEncodingKey clears the value of the "encoding_key" field.
+func (u *XunjiUpsertBulk) ClearEncodingKey() *XunjiUpsertBulk {
+	return u.Update(func(s *XunjiUpsert) {
+		s.ClearEncodingKey()
+	})
+}
+
+// SetOrganizationID sets the "organization_id" field.
+func (u *XunjiUpsertBulk) SetOrganizationID(v uint64) *XunjiUpsertBulk {
+	return u.Update(func(s *XunjiUpsert) {
+		s.SetOrganizationID(v)
+	})
+}
+
+// AddOrganizationID adds v to the "organization_id" field.
+func (u *XunjiUpsertBulk) AddOrganizationID(v uint64) *XunjiUpsertBulk {
+	return u.Update(func(s *XunjiUpsert) {
+		s.AddOrganizationID(v)
+	})
+}
+
+// UpdateOrganizationID sets the "organization_id" field to the value that was provided on create.
+func (u *XunjiUpsertBulk) UpdateOrganizationID() *XunjiUpsertBulk {
+	return u.Update(func(s *XunjiUpsert) {
+		s.UpdateOrganizationID()
+	})
+}
+
+// Exec executes the query.
+func (u *XunjiUpsertBulk) 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 XunjiCreateBulk instead", i)
+		}
+	}
+	if len(u.create.conflict) == 0 {
+		return errors.New("ent: missing options for XunjiCreateBulk.OnConflict")
+	}
+	return u.create.Exec(ctx)
+}
+
+// ExecX is like Exec, but panics if an error occurs.
+func (u *XunjiUpsertBulk) ExecX(ctx context.Context) {
+	if err := u.create.Exec(ctx); err != nil {
+		panic(err)
+	}
+}

+ 88 - 0
ent/xunji_delete.go

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

+ 526 - 0
ent/xunji_query.go

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

+ 636 - 0
ent/xunji_update.go

@@ -0,0 +1,636 @@
+// Code generated by ent, DO NOT EDIT.
+
+package ent
+
+import (
+	"context"
+	"errors"
+	"fmt"
+	"time"
+	"wechat-api/ent/predicate"
+	"wechat-api/ent/xunji"
+
+	"entgo.io/ent/dialect/sql"
+	"entgo.io/ent/dialect/sql/sqlgraph"
+	"entgo.io/ent/schema/field"
+)
+
+// XunjiUpdate is the builder for updating Xunji entities.
+type XunjiUpdate struct {
+	config
+	hooks    []Hook
+	mutation *XunjiMutation
+}
+
+// Where appends a list predicates to the XunjiUpdate builder.
+func (xu *XunjiUpdate) Where(ps ...predicate.Xunji) *XunjiUpdate {
+	xu.mutation.Where(ps...)
+	return xu
+}
+
+// SetUpdatedAt sets the "updated_at" field.
+func (xu *XunjiUpdate) SetUpdatedAt(t time.Time) *XunjiUpdate {
+	xu.mutation.SetUpdatedAt(t)
+	return xu
+}
+
+// SetStatus sets the "status" field.
+func (xu *XunjiUpdate) SetStatus(u uint8) *XunjiUpdate {
+	xu.mutation.ResetStatus()
+	xu.mutation.SetStatus(u)
+	return xu
+}
+
+// SetNillableStatus sets the "status" field if the given value is not nil.
+func (xu *XunjiUpdate) SetNillableStatus(u *uint8) *XunjiUpdate {
+	if u != nil {
+		xu.SetStatus(*u)
+	}
+	return xu
+}
+
+// AddStatus adds u to the "status" field.
+func (xu *XunjiUpdate) AddStatus(u int8) *XunjiUpdate {
+	xu.mutation.AddStatus(u)
+	return xu
+}
+
+// ClearStatus clears the value of the "status" field.
+func (xu *XunjiUpdate) ClearStatus() *XunjiUpdate {
+	xu.mutation.ClearStatus()
+	return xu
+}
+
+// SetDeletedAt sets the "deleted_at" field.
+func (xu *XunjiUpdate) SetDeletedAt(t time.Time) *XunjiUpdate {
+	xu.mutation.SetDeletedAt(t)
+	return xu
+}
+
+// SetNillableDeletedAt sets the "deleted_at" field if the given value is not nil.
+func (xu *XunjiUpdate) SetNillableDeletedAt(t *time.Time) *XunjiUpdate {
+	if t != nil {
+		xu.SetDeletedAt(*t)
+	}
+	return xu
+}
+
+// ClearDeletedAt clears the value of the "deleted_at" field.
+func (xu *XunjiUpdate) ClearDeletedAt() *XunjiUpdate {
+	xu.mutation.ClearDeletedAt()
+	return xu
+}
+
+// SetAppKey sets the "app_key" field.
+func (xu *XunjiUpdate) SetAppKey(s string) *XunjiUpdate {
+	xu.mutation.SetAppKey(s)
+	return xu
+}
+
+// SetNillableAppKey sets the "app_key" field if the given value is not nil.
+func (xu *XunjiUpdate) SetNillableAppKey(s *string) *XunjiUpdate {
+	if s != nil {
+		xu.SetAppKey(*s)
+	}
+	return xu
+}
+
+// ClearAppKey clears the value of the "app_key" field.
+func (xu *XunjiUpdate) ClearAppKey() *XunjiUpdate {
+	xu.mutation.ClearAppKey()
+	return xu
+}
+
+// SetAppSecret sets the "app_secret" field.
+func (xu *XunjiUpdate) SetAppSecret(s string) *XunjiUpdate {
+	xu.mutation.SetAppSecret(s)
+	return xu
+}
+
+// SetNillableAppSecret sets the "app_secret" field if the given value is not nil.
+func (xu *XunjiUpdate) SetNillableAppSecret(s *string) *XunjiUpdate {
+	if s != nil {
+		xu.SetAppSecret(*s)
+	}
+	return xu
+}
+
+// ClearAppSecret clears the value of the "app_secret" field.
+func (xu *XunjiUpdate) ClearAppSecret() *XunjiUpdate {
+	xu.mutation.ClearAppSecret()
+	return xu
+}
+
+// SetToken sets the "token" field.
+func (xu *XunjiUpdate) SetToken(s string) *XunjiUpdate {
+	xu.mutation.SetToken(s)
+	return xu
+}
+
+// SetNillableToken sets the "token" field if the given value is not nil.
+func (xu *XunjiUpdate) SetNillableToken(s *string) *XunjiUpdate {
+	if s != nil {
+		xu.SetToken(*s)
+	}
+	return xu
+}
+
+// ClearToken clears the value of the "token" field.
+func (xu *XunjiUpdate) ClearToken() *XunjiUpdate {
+	xu.mutation.ClearToken()
+	return xu
+}
+
+// SetEncodingKey sets the "encoding_key" field.
+func (xu *XunjiUpdate) SetEncodingKey(s string) *XunjiUpdate {
+	xu.mutation.SetEncodingKey(s)
+	return xu
+}
+
+// SetNillableEncodingKey sets the "encoding_key" field if the given value is not nil.
+func (xu *XunjiUpdate) SetNillableEncodingKey(s *string) *XunjiUpdate {
+	if s != nil {
+		xu.SetEncodingKey(*s)
+	}
+	return xu
+}
+
+// ClearEncodingKey clears the value of the "encoding_key" field.
+func (xu *XunjiUpdate) ClearEncodingKey() *XunjiUpdate {
+	xu.mutation.ClearEncodingKey()
+	return xu
+}
+
+// SetOrganizationID sets the "organization_id" field.
+func (xu *XunjiUpdate) SetOrganizationID(u uint64) *XunjiUpdate {
+	xu.mutation.ResetOrganizationID()
+	xu.mutation.SetOrganizationID(u)
+	return xu
+}
+
+// SetNillableOrganizationID sets the "organization_id" field if the given value is not nil.
+func (xu *XunjiUpdate) SetNillableOrganizationID(u *uint64) *XunjiUpdate {
+	if u != nil {
+		xu.SetOrganizationID(*u)
+	}
+	return xu
+}
+
+// AddOrganizationID adds u to the "organization_id" field.
+func (xu *XunjiUpdate) AddOrganizationID(u int64) *XunjiUpdate {
+	xu.mutation.AddOrganizationID(u)
+	return xu
+}
+
+// Mutation returns the XunjiMutation object of the builder.
+func (xu *XunjiUpdate) Mutation() *XunjiMutation {
+	return xu.mutation
+}
+
+// Save executes the query and returns the number of nodes affected by the update operation.
+func (xu *XunjiUpdate) Save(ctx context.Context) (int, error) {
+	if err := xu.defaults(); err != nil {
+		return 0, err
+	}
+	return withHooks(ctx, xu.sqlSave, xu.mutation, xu.hooks)
+}
+
+// SaveX is like Save, but panics if an error occurs.
+func (xu *XunjiUpdate) SaveX(ctx context.Context) int {
+	affected, err := xu.Save(ctx)
+	if err != nil {
+		panic(err)
+	}
+	return affected
+}
+
+// Exec executes the query.
+func (xu *XunjiUpdate) Exec(ctx context.Context) error {
+	_, err := xu.Save(ctx)
+	return err
+}
+
+// ExecX is like Exec, but panics if an error occurs.
+func (xu *XunjiUpdate) ExecX(ctx context.Context) {
+	if err := xu.Exec(ctx); err != nil {
+		panic(err)
+	}
+}
+
+// defaults sets the default values of the builder before save.
+func (xu *XunjiUpdate) defaults() error {
+	if _, ok := xu.mutation.UpdatedAt(); !ok {
+		if xunji.UpdateDefaultUpdatedAt == nil {
+			return fmt.Errorf("ent: uninitialized xunji.UpdateDefaultUpdatedAt (forgotten import ent/runtime?)")
+		}
+		v := xunji.UpdateDefaultUpdatedAt()
+		xu.mutation.SetUpdatedAt(v)
+	}
+	return nil
+}
+
+// check runs all checks and user-defined validators on the builder.
+func (xu *XunjiUpdate) check() error {
+	if v, ok := xu.mutation.OrganizationID(); ok {
+		if err := xunji.OrganizationIDValidator(v); err != nil {
+			return &ValidationError{Name: "organization_id", err: fmt.Errorf(`ent: validator failed for field "Xunji.organization_id": %w`, err)}
+		}
+	}
+	return nil
+}
+
+func (xu *XunjiUpdate) sqlSave(ctx context.Context) (n int, err error) {
+	if err := xu.check(); err != nil {
+		return n, err
+	}
+	_spec := sqlgraph.NewUpdateSpec(xunji.Table, xunji.Columns, sqlgraph.NewFieldSpec(xunji.FieldID, field.TypeUint64))
+	if ps := xu.mutation.predicates; len(ps) > 0 {
+		_spec.Predicate = func(selector *sql.Selector) {
+			for i := range ps {
+				ps[i](selector)
+			}
+		}
+	}
+	if value, ok := xu.mutation.UpdatedAt(); ok {
+		_spec.SetField(xunji.FieldUpdatedAt, field.TypeTime, value)
+	}
+	if value, ok := xu.mutation.Status(); ok {
+		_spec.SetField(xunji.FieldStatus, field.TypeUint8, value)
+	}
+	if value, ok := xu.mutation.AddedStatus(); ok {
+		_spec.AddField(xunji.FieldStatus, field.TypeUint8, value)
+	}
+	if xu.mutation.StatusCleared() {
+		_spec.ClearField(xunji.FieldStatus, field.TypeUint8)
+	}
+	if value, ok := xu.mutation.DeletedAt(); ok {
+		_spec.SetField(xunji.FieldDeletedAt, field.TypeTime, value)
+	}
+	if xu.mutation.DeletedAtCleared() {
+		_spec.ClearField(xunji.FieldDeletedAt, field.TypeTime)
+	}
+	if value, ok := xu.mutation.AppKey(); ok {
+		_spec.SetField(xunji.FieldAppKey, field.TypeString, value)
+	}
+	if xu.mutation.AppKeyCleared() {
+		_spec.ClearField(xunji.FieldAppKey, field.TypeString)
+	}
+	if value, ok := xu.mutation.AppSecret(); ok {
+		_spec.SetField(xunji.FieldAppSecret, field.TypeString, value)
+	}
+	if xu.mutation.AppSecretCleared() {
+		_spec.ClearField(xunji.FieldAppSecret, field.TypeString)
+	}
+	if value, ok := xu.mutation.Token(); ok {
+		_spec.SetField(xunji.FieldToken, field.TypeString, value)
+	}
+	if xu.mutation.TokenCleared() {
+		_spec.ClearField(xunji.FieldToken, field.TypeString)
+	}
+	if value, ok := xu.mutation.EncodingKey(); ok {
+		_spec.SetField(xunji.FieldEncodingKey, field.TypeString, value)
+	}
+	if xu.mutation.EncodingKeyCleared() {
+		_spec.ClearField(xunji.FieldEncodingKey, field.TypeString)
+	}
+	if value, ok := xu.mutation.OrganizationID(); ok {
+		_spec.SetField(xunji.FieldOrganizationID, field.TypeUint64, value)
+	}
+	if value, ok := xu.mutation.AddedOrganizationID(); ok {
+		_spec.AddField(xunji.FieldOrganizationID, field.TypeUint64, value)
+	}
+	if n, err = sqlgraph.UpdateNodes(ctx, xu.driver, _spec); err != nil {
+		if _, ok := err.(*sqlgraph.NotFoundError); ok {
+			err = &NotFoundError{xunji.Label}
+		} else if sqlgraph.IsConstraintError(err) {
+			err = &ConstraintError{msg: err.Error(), wrap: err}
+		}
+		return 0, err
+	}
+	xu.mutation.done = true
+	return n, nil
+}
+
+// XunjiUpdateOne is the builder for updating a single Xunji entity.
+type XunjiUpdateOne struct {
+	config
+	fields   []string
+	hooks    []Hook
+	mutation *XunjiMutation
+}
+
+// SetUpdatedAt sets the "updated_at" field.
+func (xuo *XunjiUpdateOne) SetUpdatedAt(t time.Time) *XunjiUpdateOne {
+	xuo.mutation.SetUpdatedAt(t)
+	return xuo
+}
+
+// SetStatus sets the "status" field.
+func (xuo *XunjiUpdateOne) SetStatus(u uint8) *XunjiUpdateOne {
+	xuo.mutation.ResetStatus()
+	xuo.mutation.SetStatus(u)
+	return xuo
+}
+
+// SetNillableStatus sets the "status" field if the given value is not nil.
+func (xuo *XunjiUpdateOne) SetNillableStatus(u *uint8) *XunjiUpdateOne {
+	if u != nil {
+		xuo.SetStatus(*u)
+	}
+	return xuo
+}
+
+// AddStatus adds u to the "status" field.
+func (xuo *XunjiUpdateOne) AddStatus(u int8) *XunjiUpdateOne {
+	xuo.mutation.AddStatus(u)
+	return xuo
+}
+
+// ClearStatus clears the value of the "status" field.
+func (xuo *XunjiUpdateOne) ClearStatus() *XunjiUpdateOne {
+	xuo.mutation.ClearStatus()
+	return xuo
+}
+
+// SetDeletedAt sets the "deleted_at" field.
+func (xuo *XunjiUpdateOne) SetDeletedAt(t time.Time) *XunjiUpdateOne {
+	xuo.mutation.SetDeletedAt(t)
+	return xuo
+}
+
+// SetNillableDeletedAt sets the "deleted_at" field if the given value is not nil.
+func (xuo *XunjiUpdateOne) SetNillableDeletedAt(t *time.Time) *XunjiUpdateOne {
+	if t != nil {
+		xuo.SetDeletedAt(*t)
+	}
+	return xuo
+}
+
+// ClearDeletedAt clears the value of the "deleted_at" field.
+func (xuo *XunjiUpdateOne) ClearDeletedAt() *XunjiUpdateOne {
+	xuo.mutation.ClearDeletedAt()
+	return xuo
+}
+
+// SetAppKey sets the "app_key" field.
+func (xuo *XunjiUpdateOne) SetAppKey(s string) *XunjiUpdateOne {
+	xuo.mutation.SetAppKey(s)
+	return xuo
+}
+
+// SetNillableAppKey sets the "app_key" field if the given value is not nil.
+func (xuo *XunjiUpdateOne) SetNillableAppKey(s *string) *XunjiUpdateOne {
+	if s != nil {
+		xuo.SetAppKey(*s)
+	}
+	return xuo
+}
+
+// ClearAppKey clears the value of the "app_key" field.
+func (xuo *XunjiUpdateOne) ClearAppKey() *XunjiUpdateOne {
+	xuo.mutation.ClearAppKey()
+	return xuo
+}
+
+// SetAppSecret sets the "app_secret" field.
+func (xuo *XunjiUpdateOne) SetAppSecret(s string) *XunjiUpdateOne {
+	xuo.mutation.SetAppSecret(s)
+	return xuo
+}
+
+// SetNillableAppSecret sets the "app_secret" field if the given value is not nil.
+func (xuo *XunjiUpdateOne) SetNillableAppSecret(s *string) *XunjiUpdateOne {
+	if s != nil {
+		xuo.SetAppSecret(*s)
+	}
+	return xuo
+}
+
+// ClearAppSecret clears the value of the "app_secret" field.
+func (xuo *XunjiUpdateOne) ClearAppSecret() *XunjiUpdateOne {
+	xuo.mutation.ClearAppSecret()
+	return xuo
+}
+
+// SetToken sets the "token" field.
+func (xuo *XunjiUpdateOne) SetToken(s string) *XunjiUpdateOne {
+	xuo.mutation.SetToken(s)
+	return xuo
+}
+
+// SetNillableToken sets the "token" field if the given value is not nil.
+func (xuo *XunjiUpdateOne) SetNillableToken(s *string) *XunjiUpdateOne {
+	if s != nil {
+		xuo.SetToken(*s)
+	}
+	return xuo
+}
+
+// ClearToken clears the value of the "token" field.
+func (xuo *XunjiUpdateOne) ClearToken() *XunjiUpdateOne {
+	xuo.mutation.ClearToken()
+	return xuo
+}
+
+// SetEncodingKey sets the "encoding_key" field.
+func (xuo *XunjiUpdateOne) SetEncodingKey(s string) *XunjiUpdateOne {
+	xuo.mutation.SetEncodingKey(s)
+	return xuo
+}
+
+// SetNillableEncodingKey sets the "encoding_key" field if the given value is not nil.
+func (xuo *XunjiUpdateOne) SetNillableEncodingKey(s *string) *XunjiUpdateOne {
+	if s != nil {
+		xuo.SetEncodingKey(*s)
+	}
+	return xuo
+}
+
+// ClearEncodingKey clears the value of the "encoding_key" field.
+func (xuo *XunjiUpdateOne) ClearEncodingKey() *XunjiUpdateOne {
+	xuo.mutation.ClearEncodingKey()
+	return xuo
+}
+
+// SetOrganizationID sets the "organization_id" field.
+func (xuo *XunjiUpdateOne) SetOrganizationID(u uint64) *XunjiUpdateOne {
+	xuo.mutation.ResetOrganizationID()
+	xuo.mutation.SetOrganizationID(u)
+	return xuo
+}
+
+// SetNillableOrganizationID sets the "organization_id" field if the given value is not nil.
+func (xuo *XunjiUpdateOne) SetNillableOrganizationID(u *uint64) *XunjiUpdateOne {
+	if u != nil {
+		xuo.SetOrganizationID(*u)
+	}
+	return xuo
+}
+
+// AddOrganizationID adds u to the "organization_id" field.
+func (xuo *XunjiUpdateOne) AddOrganizationID(u int64) *XunjiUpdateOne {
+	xuo.mutation.AddOrganizationID(u)
+	return xuo
+}
+
+// Mutation returns the XunjiMutation object of the builder.
+func (xuo *XunjiUpdateOne) Mutation() *XunjiMutation {
+	return xuo.mutation
+}
+
+// Where appends a list predicates to the XunjiUpdate builder.
+func (xuo *XunjiUpdateOne) Where(ps ...predicate.Xunji) *XunjiUpdateOne {
+	xuo.mutation.Where(ps...)
+	return xuo
+}
+
+// Select allows selecting one or more fields (columns) of the returned entity.
+// The default is selecting all fields defined in the entity schema.
+func (xuo *XunjiUpdateOne) Select(field string, fields ...string) *XunjiUpdateOne {
+	xuo.fields = append([]string{field}, fields...)
+	return xuo
+}
+
+// Save executes the query and returns the updated Xunji entity.
+func (xuo *XunjiUpdateOne) Save(ctx context.Context) (*Xunji, error) {
+	if err := xuo.defaults(); err != nil {
+		return nil, err
+	}
+	return withHooks(ctx, xuo.sqlSave, xuo.mutation, xuo.hooks)
+}
+
+// SaveX is like Save, but panics if an error occurs.
+func (xuo *XunjiUpdateOne) SaveX(ctx context.Context) *Xunji {
+	node, err := xuo.Save(ctx)
+	if err != nil {
+		panic(err)
+	}
+	return node
+}
+
+// Exec executes the query on the entity.
+func (xuo *XunjiUpdateOne) Exec(ctx context.Context) error {
+	_, err := xuo.Save(ctx)
+	return err
+}
+
+// ExecX is like Exec, but panics if an error occurs.
+func (xuo *XunjiUpdateOne) ExecX(ctx context.Context) {
+	if err := xuo.Exec(ctx); err != nil {
+		panic(err)
+	}
+}
+
+// defaults sets the default values of the builder before save.
+func (xuo *XunjiUpdateOne) defaults() error {
+	if _, ok := xuo.mutation.UpdatedAt(); !ok {
+		if xunji.UpdateDefaultUpdatedAt == nil {
+			return fmt.Errorf("ent: uninitialized xunji.UpdateDefaultUpdatedAt (forgotten import ent/runtime?)")
+		}
+		v := xunji.UpdateDefaultUpdatedAt()
+		xuo.mutation.SetUpdatedAt(v)
+	}
+	return nil
+}
+
+// check runs all checks and user-defined validators on the builder.
+func (xuo *XunjiUpdateOne) check() error {
+	if v, ok := xuo.mutation.OrganizationID(); ok {
+		if err := xunji.OrganizationIDValidator(v); err != nil {
+			return &ValidationError{Name: "organization_id", err: fmt.Errorf(`ent: validator failed for field "Xunji.organization_id": %w`, err)}
+		}
+	}
+	return nil
+}
+
+func (xuo *XunjiUpdateOne) sqlSave(ctx context.Context) (_node *Xunji, err error) {
+	if err := xuo.check(); err != nil {
+		return _node, err
+	}
+	_spec := sqlgraph.NewUpdateSpec(xunji.Table, xunji.Columns, sqlgraph.NewFieldSpec(xunji.FieldID, field.TypeUint64))
+	id, ok := xuo.mutation.ID()
+	if !ok {
+		return nil, &ValidationError{Name: "id", err: errors.New(`ent: missing "Xunji.id" for update`)}
+	}
+	_spec.Node.ID.Value = id
+	if fields := xuo.fields; len(fields) > 0 {
+		_spec.Node.Columns = make([]string, 0, len(fields))
+		_spec.Node.Columns = append(_spec.Node.Columns, xunji.FieldID)
+		for _, f := range fields {
+			if !xunji.ValidColumn(f) {
+				return nil, &ValidationError{Name: f, err: fmt.Errorf("ent: invalid field %q for query", f)}
+			}
+			if f != xunji.FieldID {
+				_spec.Node.Columns = append(_spec.Node.Columns, f)
+			}
+		}
+	}
+	if ps := xuo.mutation.predicates; len(ps) > 0 {
+		_spec.Predicate = func(selector *sql.Selector) {
+			for i := range ps {
+				ps[i](selector)
+			}
+		}
+	}
+	if value, ok := xuo.mutation.UpdatedAt(); ok {
+		_spec.SetField(xunji.FieldUpdatedAt, field.TypeTime, value)
+	}
+	if value, ok := xuo.mutation.Status(); ok {
+		_spec.SetField(xunji.FieldStatus, field.TypeUint8, value)
+	}
+	if value, ok := xuo.mutation.AddedStatus(); ok {
+		_spec.AddField(xunji.FieldStatus, field.TypeUint8, value)
+	}
+	if xuo.mutation.StatusCleared() {
+		_spec.ClearField(xunji.FieldStatus, field.TypeUint8)
+	}
+	if value, ok := xuo.mutation.DeletedAt(); ok {
+		_spec.SetField(xunji.FieldDeletedAt, field.TypeTime, value)
+	}
+	if xuo.mutation.DeletedAtCleared() {
+		_spec.ClearField(xunji.FieldDeletedAt, field.TypeTime)
+	}
+	if value, ok := xuo.mutation.AppKey(); ok {
+		_spec.SetField(xunji.FieldAppKey, field.TypeString, value)
+	}
+	if xuo.mutation.AppKeyCleared() {
+		_spec.ClearField(xunji.FieldAppKey, field.TypeString)
+	}
+	if value, ok := xuo.mutation.AppSecret(); ok {
+		_spec.SetField(xunji.FieldAppSecret, field.TypeString, value)
+	}
+	if xuo.mutation.AppSecretCleared() {
+		_spec.ClearField(xunji.FieldAppSecret, field.TypeString)
+	}
+	if value, ok := xuo.mutation.Token(); ok {
+		_spec.SetField(xunji.FieldToken, field.TypeString, value)
+	}
+	if xuo.mutation.TokenCleared() {
+		_spec.ClearField(xunji.FieldToken, field.TypeString)
+	}
+	if value, ok := xuo.mutation.EncodingKey(); ok {
+		_spec.SetField(xunji.FieldEncodingKey, field.TypeString, value)
+	}
+	if xuo.mutation.EncodingKeyCleared() {
+		_spec.ClearField(xunji.FieldEncodingKey, field.TypeString)
+	}
+	if value, ok := xuo.mutation.OrganizationID(); ok {
+		_spec.SetField(xunji.FieldOrganizationID, field.TypeUint64, value)
+	}
+	if value, ok := xuo.mutation.AddedOrganizationID(); ok {
+		_spec.AddField(xunji.FieldOrganizationID, field.TypeUint64, value)
+	}
+	_node = &Xunji{config: xuo.config}
+	_spec.Assign = _node.assignValues
+	_spec.ScanValues = _node.scanValues
+	if err = sqlgraph.UpdateNode(ctx, xuo.driver, _spec); err != nil {
+		if _, ok := err.(*sqlgraph.NotFoundError); ok {
+			err = &NotFoundError{xunji.Label}
+		} else if sqlgraph.IsConstraintError(err) {
+			err = &ConstraintError{msg: err.Error(), wrap: err}
+		}
+		return nil, err
+	}
+	xuo.mutation.done = true
+	return _node, nil
+}

+ 234 - 0
ent/xunjiservice.go

@@ -0,0 +1,234 @@
+// Code generated by ent, DO NOT EDIT.
+
+package ent
+
+import (
+	"fmt"
+	"strings"
+	"time"
+	"wechat-api/ent/agent"
+	"wechat-api/ent/xunjiservice"
+
+	"entgo.io/ent"
+	"entgo.io/ent/dialect/sql"
+)
+
+// XunjiService is the model entity for the XunjiService schema.
+type XunjiService 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"`
+	// Xunji表ID
+	XunjiID uint64 `json:"xunji_id,omitempty"`
+	// 智能体ID
+	AgentID uint64 `json:"agent_id,omitempty"`
+	// organization_id | 租户ID
+	OrganizationID uint64 `json:"organization_id,omitempty"`
+	// 微信ID
+	Wxid string `json:"wxid,omitempty"`
+	// 大模型服务地址
+	APIBase string `json:"api_base,omitempty"`
+	// 大模型服务密钥
+	APIKey string `json:"api_key,omitempty"`
+	// Edges holds the relations/edges for other nodes in the graph.
+	// The values are being populated by the XunjiServiceQuery when eager-loading is set.
+	Edges        XunjiServiceEdges `json:"edges"`
+	selectValues sql.SelectValues
+}
+
+// XunjiServiceEdges holds the relations/edges for other nodes in the graph.
+type XunjiServiceEdges struct {
+	// Agent holds the value of the agent edge.
+	Agent *Agent `json:"agent,omitempty"`
+	// loadedTypes holds the information for reporting if a
+	// type was loaded (or requested) in eager-loading or not.
+	loadedTypes [1]bool
+}
+
+// AgentOrErr returns the Agent value or an error if the edge
+// was not loaded in eager-loading, or loaded but was not found.
+func (e XunjiServiceEdges) AgentOrErr() (*Agent, error) {
+	if e.Agent != nil {
+		return e.Agent, nil
+	} else if e.loadedTypes[0] {
+		return nil, &NotFoundError{label: agent.Label}
+	}
+	return nil, &NotLoadedError{edge: "agent"}
+}
+
+// scanValues returns the types for scanning values from sql.Rows.
+func (*XunjiService) scanValues(columns []string) ([]any, error) {
+	values := make([]any, len(columns))
+	for i := range columns {
+		switch columns[i] {
+		case xunjiservice.FieldID, xunjiservice.FieldStatus, xunjiservice.FieldXunjiID, xunjiservice.FieldAgentID, xunjiservice.FieldOrganizationID:
+			values[i] = new(sql.NullInt64)
+		case xunjiservice.FieldWxid, xunjiservice.FieldAPIBase, xunjiservice.FieldAPIKey:
+			values[i] = new(sql.NullString)
+		case xunjiservice.FieldCreatedAt, xunjiservice.FieldUpdatedAt, xunjiservice.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 XunjiService fields.
+func (xs *XunjiService) 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 xunjiservice.FieldID:
+			value, ok := values[i].(*sql.NullInt64)
+			if !ok {
+				return fmt.Errorf("unexpected type %T for field id", value)
+			}
+			xs.ID = uint64(value.Int64)
+		case xunjiservice.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 {
+				xs.CreatedAt = value.Time
+			}
+		case xunjiservice.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 {
+				xs.UpdatedAt = value.Time
+			}
+		case xunjiservice.FieldStatus:
+			if value, ok := values[i].(*sql.NullInt64); !ok {
+				return fmt.Errorf("unexpected type %T for field status", values[i])
+			} else if value.Valid {
+				xs.Status = uint8(value.Int64)
+			}
+		case xunjiservice.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 {
+				xs.DeletedAt = value.Time
+			}
+		case xunjiservice.FieldXunjiID:
+			if value, ok := values[i].(*sql.NullInt64); !ok {
+				return fmt.Errorf("unexpected type %T for field xunji_id", values[i])
+			} else if value.Valid {
+				xs.XunjiID = uint64(value.Int64)
+			}
+		case xunjiservice.FieldAgentID:
+			if value, ok := values[i].(*sql.NullInt64); !ok {
+				return fmt.Errorf("unexpected type %T for field agent_id", values[i])
+			} else if value.Valid {
+				xs.AgentID = uint64(value.Int64)
+			}
+		case xunjiservice.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 {
+				xs.OrganizationID = uint64(value.Int64)
+			}
+		case xunjiservice.FieldWxid:
+			if value, ok := values[i].(*sql.NullString); !ok {
+				return fmt.Errorf("unexpected type %T for field wxid", values[i])
+			} else if value.Valid {
+				xs.Wxid = value.String
+			}
+		case xunjiservice.FieldAPIBase:
+			if value, ok := values[i].(*sql.NullString); !ok {
+				return fmt.Errorf("unexpected type %T for field api_base", values[i])
+			} else if value.Valid {
+				xs.APIBase = value.String
+			}
+		case xunjiservice.FieldAPIKey:
+			if value, ok := values[i].(*sql.NullString); !ok {
+				return fmt.Errorf("unexpected type %T for field api_key", values[i])
+			} else if value.Valid {
+				xs.APIKey = value.String
+			}
+		default:
+			xs.selectValues.Set(columns[i], values[i])
+		}
+	}
+	return nil
+}
+
+// Value returns the ent.Value that was dynamically selected and assigned to the XunjiService.
+// This includes values selected through modifiers, order, etc.
+func (xs *XunjiService) Value(name string) (ent.Value, error) {
+	return xs.selectValues.Get(name)
+}
+
+// QueryAgent queries the "agent" edge of the XunjiService entity.
+func (xs *XunjiService) QueryAgent() *AgentQuery {
+	return NewXunjiServiceClient(xs.config).QueryAgent(xs)
+}
+
+// Update returns a builder for updating this XunjiService.
+// Note that you need to call XunjiService.Unwrap() before calling this method if this XunjiService
+// was returned from a transaction, and the transaction was committed or rolled back.
+func (xs *XunjiService) Update() *XunjiServiceUpdateOne {
+	return NewXunjiServiceClient(xs.config).UpdateOne(xs)
+}
+
+// Unwrap unwraps the XunjiService 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 (xs *XunjiService) Unwrap() *XunjiService {
+	_tx, ok := xs.config.driver.(*txDriver)
+	if !ok {
+		panic("ent: XunjiService is not a transactional entity")
+	}
+	xs.config.driver = _tx.drv
+	return xs
+}
+
+// String implements the fmt.Stringer.
+func (xs *XunjiService) String() string {
+	var builder strings.Builder
+	builder.WriteString("XunjiService(")
+	builder.WriteString(fmt.Sprintf("id=%v, ", xs.ID))
+	builder.WriteString("created_at=")
+	builder.WriteString(xs.CreatedAt.Format(time.ANSIC))
+	builder.WriteString(", ")
+	builder.WriteString("updated_at=")
+	builder.WriteString(xs.UpdatedAt.Format(time.ANSIC))
+	builder.WriteString(", ")
+	builder.WriteString("status=")
+	builder.WriteString(fmt.Sprintf("%v", xs.Status))
+	builder.WriteString(", ")
+	builder.WriteString("deleted_at=")
+	builder.WriteString(xs.DeletedAt.Format(time.ANSIC))
+	builder.WriteString(", ")
+	builder.WriteString("xunji_id=")
+	builder.WriteString(fmt.Sprintf("%v", xs.XunjiID))
+	builder.WriteString(", ")
+	builder.WriteString("agent_id=")
+	builder.WriteString(fmt.Sprintf("%v", xs.AgentID))
+	builder.WriteString(", ")
+	builder.WriteString("organization_id=")
+	builder.WriteString(fmt.Sprintf("%v", xs.OrganizationID))
+	builder.WriteString(", ")
+	builder.WriteString("wxid=")
+	builder.WriteString(xs.Wxid)
+	builder.WriteString(", ")
+	builder.WriteString("api_base=")
+	builder.WriteString(xs.APIBase)
+	builder.WriteString(", ")
+	builder.WriteString("api_key=")
+	builder.WriteString(xs.APIKey)
+	builder.WriteByte(')')
+	return builder.String()
+}
+
+// XunjiServices is a parsable slice of XunjiService.
+type XunjiServices []*XunjiService

+ 639 - 0
ent/xunjiservice/where.go

@@ -0,0 +1,639 @@
+// Code generated by ent, DO NOT EDIT.
+
+package xunjiservice
+
+import (
+	"time"
+	"wechat-api/ent/predicate"
+
+	"entgo.io/ent/dialect/sql"
+	"entgo.io/ent/dialect/sql/sqlgraph"
+)
+
+// ID filters vertices based on their ID field.
+func ID(id uint64) predicate.XunjiService {
+	return predicate.XunjiService(sql.FieldEQ(FieldID, id))
+}
+
+// IDEQ applies the EQ predicate on the ID field.
+func IDEQ(id uint64) predicate.XunjiService {
+	return predicate.XunjiService(sql.FieldEQ(FieldID, id))
+}
+
+// IDNEQ applies the NEQ predicate on the ID field.
+func IDNEQ(id uint64) predicate.XunjiService {
+	return predicate.XunjiService(sql.FieldNEQ(FieldID, id))
+}
+
+// IDIn applies the In predicate on the ID field.
+func IDIn(ids ...uint64) predicate.XunjiService {
+	return predicate.XunjiService(sql.FieldIn(FieldID, ids...))
+}
+
+// IDNotIn applies the NotIn predicate on the ID field.
+func IDNotIn(ids ...uint64) predicate.XunjiService {
+	return predicate.XunjiService(sql.FieldNotIn(FieldID, ids...))
+}
+
+// IDGT applies the GT predicate on the ID field.
+func IDGT(id uint64) predicate.XunjiService {
+	return predicate.XunjiService(sql.FieldGT(FieldID, id))
+}
+
+// IDGTE applies the GTE predicate on the ID field.
+func IDGTE(id uint64) predicate.XunjiService {
+	return predicate.XunjiService(sql.FieldGTE(FieldID, id))
+}
+
+// IDLT applies the LT predicate on the ID field.
+func IDLT(id uint64) predicate.XunjiService {
+	return predicate.XunjiService(sql.FieldLT(FieldID, id))
+}
+
+// IDLTE applies the LTE predicate on the ID field.
+func IDLTE(id uint64) predicate.XunjiService {
+	return predicate.XunjiService(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.XunjiService {
+	return predicate.XunjiService(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.XunjiService {
+	return predicate.XunjiService(sql.FieldEQ(FieldUpdatedAt, v))
+}
+
+// Status applies equality check predicate on the "status" field. It's identical to StatusEQ.
+func Status(v uint8) predicate.XunjiService {
+	return predicate.XunjiService(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.XunjiService {
+	return predicate.XunjiService(sql.FieldEQ(FieldDeletedAt, v))
+}
+
+// XunjiID applies equality check predicate on the "xunji_id" field. It's identical to XunjiIDEQ.
+func XunjiID(v uint64) predicate.XunjiService {
+	return predicate.XunjiService(sql.FieldEQ(FieldXunjiID, v))
+}
+
+// AgentID applies equality check predicate on the "agent_id" field. It's identical to AgentIDEQ.
+func AgentID(v uint64) predicate.XunjiService {
+	return predicate.XunjiService(sql.FieldEQ(FieldAgentID, v))
+}
+
+// OrganizationID applies equality check predicate on the "organization_id" field. It's identical to OrganizationIDEQ.
+func OrganizationID(v uint64) predicate.XunjiService {
+	return predicate.XunjiService(sql.FieldEQ(FieldOrganizationID, v))
+}
+
+// Wxid applies equality check predicate on the "wxid" field. It's identical to WxidEQ.
+func Wxid(v string) predicate.XunjiService {
+	return predicate.XunjiService(sql.FieldEQ(FieldWxid, v))
+}
+
+// APIBase applies equality check predicate on the "api_base" field. It's identical to APIBaseEQ.
+func APIBase(v string) predicate.XunjiService {
+	return predicate.XunjiService(sql.FieldEQ(FieldAPIBase, v))
+}
+
+// APIKey applies equality check predicate on the "api_key" field. It's identical to APIKeyEQ.
+func APIKey(v string) predicate.XunjiService {
+	return predicate.XunjiService(sql.FieldEQ(FieldAPIKey, v))
+}
+
+// CreatedAtEQ applies the EQ predicate on the "created_at" field.
+func CreatedAtEQ(v time.Time) predicate.XunjiService {
+	return predicate.XunjiService(sql.FieldEQ(FieldCreatedAt, v))
+}
+
+// CreatedAtNEQ applies the NEQ predicate on the "created_at" field.
+func CreatedAtNEQ(v time.Time) predicate.XunjiService {
+	return predicate.XunjiService(sql.FieldNEQ(FieldCreatedAt, v))
+}
+
+// CreatedAtIn applies the In predicate on the "created_at" field.
+func CreatedAtIn(vs ...time.Time) predicate.XunjiService {
+	return predicate.XunjiService(sql.FieldIn(FieldCreatedAt, vs...))
+}
+
+// CreatedAtNotIn applies the NotIn predicate on the "created_at" field.
+func CreatedAtNotIn(vs ...time.Time) predicate.XunjiService {
+	return predicate.XunjiService(sql.FieldNotIn(FieldCreatedAt, vs...))
+}
+
+// CreatedAtGT applies the GT predicate on the "created_at" field.
+func CreatedAtGT(v time.Time) predicate.XunjiService {
+	return predicate.XunjiService(sql.FieldGT(FieldCreatedAt, v))
+}
+
+// CreatedAtGTE applies the GTE predicate on the "created_at" field.
+func CreatedAtGTE(v time.Time) predicate.XunjiService {
+	return predicate.XunjiService(sql.FieldGTE(FieldCreatedAt, v))
+}
+
+// CreatedAtLT applies the LT predicate on the "created_at" field.
+func CreatedAtLT(v time.Time) predicate.XunjiService {
+	return predicate.XunjiService(sql.FieldLT(FieldCreatedAt, v))
+}
+
+// CreatedAtLTE applies the LTE predicate on the "created_at" field.
+func CreatedAtLTE(v time.Time) predicate.XunjiService {
+	return predicate.XunjiService(sql.FieldLTE(FieldCreatedAt, v))
+}
+
+// UpdatedAtEQ applies the EQ predicate on the "updated_at" field.
+func UpdatedAtEQ(v time.Time) predicate.XunjiService {
+	return predicate.XunjiService(sql.FieldEQ(FieldUpdatedAt, v))
+}
+
+// UpdatedAtNEQ applies the NEQ predicate on the "updated_at" field.
+func UpdatedAtNEQ(v time.Time) predicate.XunjiService {
+	return predicate.XunjiService(sql.FieldNEQ(FieldUpdatedAt, v))
+}
+
+// UpdatedAtIn applies the In predicate on the "updated_at" field.
+func UpdatedAtIn(vs ...time.Time) predicate.XunjiService {
+	return predicate.XunjiService(sql.FieldIn(FieldUpdatedAt, vs...))
+}
+
+// UpdatedAtNotIn applies the NotIn predicate on the "updated_at" field.
+func UpdatedAtNotIn(vs ...time.Time) predicate.XunjiService {
+	return predicate.XunjiService(sql.FieldNotIn(FieldUpdatedAt, vs...))
+}
+
+// UpdatedAtGT applies the GT predicate on the "updated_at" field.
+func UpdatedAtGT(v time.Time) predicate.XunjiService {
+	return predicate.XunjiService(sql.FieldGT(FieldUpdatedAt, v))
+}
+
+// UpdatedAtGTE applies the GTE predicate on the "updated_at" field.
+func UpdatedAtGTE(v time.Time) predicate.XunjiService {
+	return predicate.XunjiService(sql.FieldGTE(FieldUpdatedAt, v))
+}
+
+// UpdatedAtLT applies the LT predicate on the "updated_at" field.
+func UpdatedAtLT(v time.Time) predicate.XunjiService {
+	return predicate.XunjiService(sql.FieldLT(FieldUpdatedAt, v))
+}
+
+// UpdatedAtLTE applies the LTE predicate on the "updated_at" field.
+func UpdatedAtLTE(v time.Time) predicate.XunjiService {
+	return predicate.XunjiService(sql.FieldLTE(FieldUpdatedAt, v))
+}
+
+// StatusEQ applies the EQ predicate on the "status" field.
+func StatusEQ(v uint8) predicate.XunjiService {
+	return predicate.XunjiService(sql.FieldEQ(FieldStatus, v))
+}
+
+// StatusNEQ applies the NEQ predicate on the "status" field.
+func StatusNEQ(v uint8) predicate.XunjiService {
+	return predicate.XunjiService(sql.FieldNEQ(FieldStatus, v))
+}
+
+// StatusIn applies the In predicate on the "status" field.
+func StatusIn(vs ...uint8) predicate.XunjiService {
+	return predicate.XunjiService(sql.FieldIn(FieldStatus, vs...))
+}
+
+// StatusNotIn applies the NotIn predicate on the "status" field.
+func StatusNotIn(vs ...uint8) predicate.XunjiService {
+	return predicate.XunjiService(sql.FieldNotIn(FieldStatus, vs...))
+}
+
+// StatusGT applies the GT predicate on the "status" field.
+func StatusGT(v uint8) predicate.XunjiService {
+	return predicate.XunjiService(sql.FieldGT(FieldStatus, v))
+}
+
+// StatusGTE applies the GTE predicate on the "status" field.
+func StatusGTE(v uint8) predicate.XunjiService {
+	return predicate.XunjiService(sql.FieldGTE(FieldStatus, v))
+}
+
+// StatusLT applies the LT predicate on the "status" field.
+func StatusLT(v uint8) predicate.XunjiService {
+	return predicate.XunjiService(sql.FieldLT(FieldStatus, v))
+}
+
+// StatusLTE applies the LTE predicate on the "status" field.
+func StatusLTE(v uint8) predicate.XunjiService {
+	return predicate.XunjiService(sql.FieldLTE(FieldStatus, v))
+}
+
+// StatusIsNil applies the IsNil predicate on the "status" field.
+func StatusIsNil() predicate.XunjiService {
+	return predicate.XunjiService(sql.FieldIsNull(FieldStatus))
+}
+
+// StatusNotNil applies the NotNil predicate on the "status" field.
+func StatusNotNil() predicate.XunjiService {
+	return predicate.XunjiService(sql.FieldNotNull(FieldStatus))
+}
+
+// DeletedAtEQ applies the EQ predicate on the "deleted_at" field.
+func DeletedAtEQ(v time.Time) predicate.XunjiService {
+	return predicate.XunjiService(sql.FieldEQ(FieldDeletedAt, v))
+}
+
+// DeletedAtNEQ applies the NEQ predicate on the "deleted_at" field.
+func DeletedAtNEQ(v time.Time) predicate.XunjiService {
+	return predicate.XunjiService(sql.FieldNEQ(FieldDeletedAt, v))
+}
+
+// DeletedAtIn applies the In predicate on the "deleted_at" field.
+func DeletedAtIn(vs ...time.Time) predicate.XunjiService {
+	return predicate.XunjiService(sql.FieldIn(FieldDeletedAt, vs...))
+}
+
+// DeletedAtNotIn applies the NotIn predicate on the "deleted_at" field.
+func DeletedAtNotIn(vs ...time.Time) predicate.XunjiService {
+	return predicate.XunjiService(sql.FieldNotIn(FieldDeletedAt, vs...))
+}
+
+// DeletedAtGT applies the GT predicate on the "deleted_at" field.
+func DeletedAtGT(v time.Time) predicate.XunjiService {
+	return predicate.XunjiService(sql.FieldGT(FieldDeletedAt, v))
+}
+
+// DeletedAtGTE applies the GTE predicate on the "deleted_at" field.
+func DeletedAtGTE(v time.Time) predicate.XunjiService {
+	return predicate.XunjiService(sql.FieldGTE(FieldDeletedAt, v))
+}
+
+// DeletedAtLT applies the LT predicate on the "deleted_at" field.
+func DeletedAtLT(v time.Time) predicate.XunjiService {
+	return predicate.XunjiService(sql.FieldLT(FieldDeletedAt, v))
+}
+
+// DeletedAtLTE applies the LTE predicate on the "deleted_at" field.
+func DeletedAtLTE(v time.Time) predicate.XunjiService {
+	return predicate.XunjiService(sql.FieldLTE(FieldDeletedAt, v))
+}
+
+// DeletedAtIsNil applies the IsNil predicate on the "deleted_at" field.
+func DeletedAtIsNil() predicate.XunjiService {
+	return predicate.XunjiService(sql.FieldIsNull(FieldDeletedAt))
+}
+
+// DeletedAtNotNil applies the NotNil predicate on the "deleted_at" field.
+func DeletedAtNotNil() predicate.XunjiService {
+	return predicate.XunjiService(sql.FieldNotNull(FieldDeletedAt))
+}
+
+// XunjiIDEQ applies the EQ predicate on the "xunji_id" field.
+func XunjiIDEQ(v uint64) predicate.XunjiService {
+	return predicate.XunjiService(sql.FieldEQ(FieldXunjiID, v))
+}
+
+// XunjiIDNEQ applies the NEQ predicate on the "xunji_id" field.
+func XunjiIDNEQ(v uint64) predicate.XunjiService {
+	return predicate.XunjiService(sql.FieldNEQ(FieldXunjiID, v))
+}
+
+// XunjiIDIn applies the In predicate on the "xunji_id" field.
+func XunjiIDIn(vs ...uint64) predicate.XunjiService {
+	return predicate.XunjiService(sql.FieldIn(FieldXunjiID, vs...))
+}
+
+// XunjiIDNotIn applies the NotIn predicate on the "xunji_id" field.
+func XunjiIDNotIn(vs ...uint64) predicate.XunjiService {
+	return predicate.XunjiService(sql.FieldNotIn(FieldXunjiID, vs...))
+}
+
+// XunjiIDGT applies the GT predicate on the "xunji_id" field.
+func XunjiIDGT(v uint64) predicate.XunjiService {
+	return predicate.XunjiService(sql.FieldGT(FieldXunjiID, v))
+}
+
+// XunjiIDGTE applies the GTE predicate on the "xunji_id" field.
+func XunjiIDGTE(v uint64) predicate.XunjiService {
+	return predicate.XunjiService(sql.FieldGTE(FieldXunjiID, v))
+}
+
+// XunjiIDLT applies the LT predicate on the "xunji_id" field.
+func XunjiIDLT(v uint64) predicate.XunjiService {
+	return predicate.XunjiService(sql.FieldLT(FieldXunjiID, v))
+}
+
+// XunjiIDLTE applies the LTE predicate on the "xunji_id" field.
+func XunjiIDLTE(v uint64) predicate.XunjiService {
+	return predicate.XunjiService(sql.FieldLTE(FieldXunjiID, v))
+}
+
+// AgentIDEQ applies the EQ predicate on the "agent_id" field.
+func AgentIDEQ(v uint64) predicate.XunjiService {
+	return predicate.XunjiService(sql.FieldEQ(FieldAgentID, v))
+}
+
+// AgentIDNEQ applies the NEQ predicate on the "agent_id" field.
+func AgentIDNEQ(v uint64) predicate.XunjiService {
+	return predicate.XunjiService(sql.FieldNEQ(FieldAgentID, v))
+}
+
+// AgentIDIn applies the In predicate on the "agent_id" field.
+func AgentIDIn(vs ...uint64) predicate.XunjiService {
+	return predicate.XunjiService(sql.FieldIn(FieldAgentID, vs...))
+}
+
+// AgentIDNotIn applies the NotIn predicate on the "agent_id" field.
+func AgentIDNotIn(vs ...uint64) predicate.XunjiService {
+	return predicate.XunjiService(sql.FieldNotIn(FieldAgentID, vs...))
+}
+
+// OrganizationIDEQ applies the EQ predicate on the "organization_id" field.
+func OrganizationIDEQ(v uint64) predicate.XunjiService {
+	return predicate.XunjiService(sql.FieldEQ(FieldOrganizationID, v))
+}
+
+// OrganizationIDNEQ applies the NEQ predicate on the "organization_id" field.
+func OrganizationIDNEQ(v uint64) predicate.XunjiService {
+	return predicate.XunjiService(sql.FieldNEQ(FieldOrganizationID, v))
+}
+
+// OrganizationIDIn applies the In predicate on the "organization_id" field.
+func OrganizationIDIn(vs ...uint64) predicate.XunjiService {
+	return predicate.XunjiService(sql.FieldIn(FieldOrganizationID, vs...))
+}
+
+// OrganizationIDNotIn applies the NotIn predicate on the "organization_id" field.
+func OrganizationIDNotIn(vs ...uint64) predicate.XunjiService {
+	return predicate.XunjiService(sql.FieldNotIn(FieldOrganizationID, vs...))
+}
+
+// OrganizationIDGT applies the GT predicate on the "organization_id" field.
+func OrganizationIDGT(v uint64) predicate.XunjiService {
+	return predicate.XunjiService(sql.FieldGT(FieldOrganizationID, v))
+}
+
+// OrganizationIDGTE applies the GTE predicate on the "organization_id" field.
+func OrganizationIDGTE(v uint64) predicate.XunjiService {
+	return predicate.XunjiService(sql.FieldGTE(FieldOrganizationID, v))
+}
+
+// OrganizationIDLT applies the LT predicate on the "organization_id" field.
+func OrganizationIDLT(v uint64) predicate.XunjiService {
+	return predicate.XunjiService(sql.FieldLT(FieldOrganizationID, v))
+}
+
+// OrganizationIDLTE applies the LTE predicate on the "organization_id" field.
+func OrganizationIDLTE(v uint64) predicate.XunjiService {
+	return predicate.XunjiService(sql.FieldLTE(FieldOrganizationID, v))
+}
+
+// WxidEQ applies the EQ predicate on the "wxid" field.
+func WxidEQ(v string) predicate.XunjiService {
+	return predicate.XunjiService(sql.FieldEQ(FieldWxid, v))
+}
+
+// WxidNEQ applies the NEQ predicate on the "wxid" field.
+func WxidNEQ(v string) predicate.XunjiService {
+	return predicate.XunjiService(sql.FieldNEQ(FieldWxid, v))
+}
+
+// WxidIn applies the In predicate on the "wxid" field.
+func WxidIn(vs ...string) predicate.XunjiService {
+	return predicate.XunjiService(sql.FieldIn(FieldWxid, vs...))
+}
+
+// WxidNotIn applies the NotIn predicate on the "wxid" field.
+func WxidNotIn(vs ...string) predicate.XunjiService {
+	return predicate.XunjiService(sql.FieldNotIn(FieldWxid, vs...))
+}
+
+// WxidGT applies the GT predicate on the "wxid" field.
+func WxidGT(v string) predicate.XunjiService {
+	return predicate.XunjiService(sql.FieldGT(FieldWxid, v))
+}
+
+// WxidGTE applies the GTE predicate on the "wxid" field.
+func WxidGTE(v string) predicate.XunjiService {
+	return predicate.XunjiService(sql.FieldGTE(FieldWxid, v))
+}
+
+// WxidLT applies the LT predicate on the "wxid" field.
+func WxidLT(v string) predicate.XunjiService {
+	return predicate.XunjiService(sql.FieldLT(FieldWxid, v))
+}
+
+// WxidLTE applies the LTE predicate on the "wxid" field.
+func WxidLTE(v string) predicate.XunjiService {
+	return predicate.XunjiService(sql.FieldLTE(FieldWxid, v))
+}
+
+// WxidContains applies the Contains predicate on the "wxid" field.
+func WxidContains(v string) predicate.XunjiService {
+	return predicate.XunjiService(sql.FieldContains(FieldWxid, v))
+}
+
+// WxidHasPrefix applies the HasPrefix predicate on the "wxid" field.
+func WxidHasPrefix(v string) predicate.XunjiService {
+	return predicate.XunjiService(sql.FieldHasPrefix(FieldWxid, v))
+}
+
+// WxidHasSuffix applies the HasSuffix predicate on the "wxid" field.
+func WxidHasSuffix(v string) predicate.XunjiService {
+	return predicate.XunjiService(sql.FieldHasSuffix(FieldWxid, v))
+}
+
+// WxidEqualFold applies the EqualFold predicate on the "wxid" field.
+func WxidEqualFold(v string) predicate.XunjiService {
+	return predicate.XunjiService(sql.FieldEqualFold(FieldWxid, v))
+}
+
+// WxidContainsFold applies the ContainsFold predicate on the "wxid" field.
+func WxidContainsFold(v string) predicate.XunjiService {
+	return predicate.XunjiService(sql.FieldContainsFold(FieldWxid, v))
+}
+
+// APIBaseEQ applies the EQ predicate on the "api_base" field.
+func APIBaseEQ(v string) predicate.XunjiService {
+	return predicate.XunjiService(sql.FieldEQ(FieldAPIBase, v))
+}
+
+// APIBaseNEQ applies the NEQ predicate on the "api_base" field.
+func APIBaseNEQ(v string) predicate.XunjiService {
+	return predicate.XunjiService(sql.FieldNEQ(FieldAPIBase, v))
+}
+
+// APIBaseIn applies the In predicate on the "api_base" field.
+func APIBaseIn(vs ...string) predicate.XunjiService {
+	return predicate.XunjiService(sql.FieldIn(FieldAPIBase, vs...))
+}
+
+// APIBaseNotIn applies the NotIn predicate on the "api_base" field.
+func APIBaseNotIn(vs ...string) predicate.XunjiService {
+	return predicate.XunjiService(sql.FieldNotIn(FieldAPIBase, vs...))
+}
+
+// APIBaseGT applies the GT predicate on the "api_base" field.
+func APIBaseGT(v string) predicate.XunjiService {
+	return predicate.XunjiService(sql.FieldGT(FieldAPIBase, v))
+}
+
+// APIBaseGTE applies the GTE predicate on the "api_base" field.
+func APIBaseGTE(v string) predicate.XunjiService {
+	return predicate.XunjiService(sql.FieldGTE(FieldAPIBase, v))
+}
+
+// APIBaseLT applies the LT predicate on the "api_base" field.
+func APIBaseLT(v string) predicate.XunjiService {
+	return predicate.XunjiService(sql.FieldLT(FieldAPIBase, v))
+}
+
+// APIBaseLTE applies the LTE predicate on the "api_base" field.
+func APIBaseLTE(v string) predicate.XunjiService {
+	return predicate.XunjiService(sql.FieldLTE(FieldAPIBase, v))
+}
+
+// APIBaseContains applies the Contains predicate on the "api_base" field.
+func APIBaseContains(v string) predicate.XunjiService {
+	return predicate.XunjiService(sql.FieldContains(FieldAPIBase, v))
+}
+
+// APIBaseHasPrefix applies the HasPrefix predicate on the "api_base" field.
+func APIBaseHasPrefix(v string) predicate.XunjiService {
+	return predicate.XunjiService(sql.FieldHasPrefix(FieldAPIBase, v))
+}
+
+// APIBaseHasSuffix applies the HasSuffix predicate on the "api_base" field.
+func APIBaseHasSuffix(v string) predicate.XunjiService {
+	return predicate.XunjiService(sql.FieldHasSuffix(FieldAPIBase, v))
+}
+
+// APIBaseIsNil applies the IsNil predicate on the "api_base" field.
+func APIBaseIsNil() predicate.XunjiService {
+	return predicate.XunjiService(sql.FieldIsNull(FieldAPIBase))
+}
+
+// APIBaseNotNil applies the NotNil predicate on the "api_base" field.
+func APIBaseNotNil() predicate.XunjiService {
+	return predicate.XunjiService(sql.FieldNotNull(FieldAPIBase))
+}
+
+// APIBaseEqualFold applies the EqualFold predicate on the "api_base" field.
+func APIBaseEqualFold(v string) predicate.XunjiService {
+	return predicate.XunjiService(sql.FieldEqualFold(FieldAPIBase, v))
+}
+
+// APIBaseContainsFold applies the ContainsFold predicate on the "api_base" field.
+func APIBaseContainsFold(v string) predicate.XunjiService {
+	return predicate.XunjiService(sql.FieldContainsFold(FieldAPIBase, v))
+}
+
+// APIKeyEQ applies the EQ predicate on the "api_key" field.
+func APIKeyEQ(v string) predicate.XunjiService {
+	return predicate.XunjiService(sql.FieldEQ(FieldAPIKey, v))
+}
+
+// APIKeyNEQ applies the NEQ predicate on the "api_key" field.
+func APIKeyNEQ(v string) predicate.XunjiService {
+	return predicate.XunjiService(sql.FieldNEQ(FieldAPIKey, v))
+}
+
+// APIKeyIn applies the In predicate on the "api_key" field.
+func APIKeyIn(vs ...string) predicate.XunjiService {
+	return predicate.XunjiService(sql.FieldIn(FieldAPIKey, vs...))
+}
+
+// APIKeyNotIn applies the NotIn predicate on the "api_key" field.
+func APIKeyNotIn(vs ...string) predicate.XunjiService {
+	return predicate.XunjiService(sql.FieldNotIn(FieldAPIKey, vs...))
+}
+
+// APIKeyGT applies the GT predicate on the "api_key" field.
+func APIKeyGT(v string) predicate.XunjiService {
+	return predicate.XunjiService(sql.FieldGT(FieldAPIKey, v))
+}
+
+// APIKeyGTE applies the GTE predicate on the "api_key" field.
+func APIKeyGTE(v string) predicate.XunjiService {
+	return predicate.XunjiService(sql.FieldGTE(FieldAPIKey, v))
+}
+
+// APIKeyLT applies the LT predicate on the "api_key" field.
+func APIKeyLT(v string) predicate.XunjiService {
+	return predicate.XunjiService(sql.FieldLT(FieldAPIKey, v))
+}
+
+// APIKeyLTE applies the LTE predicate on the "api_key" field.
+func APIKeyLTE(v string) predicate.XunjiService {
+	return predicate.XunjiService(sql.FieldLTE(FieldAPIKey, v))
+}
+
+// APIKeyContains applies the Contains predicate on the "api_key" field.
+func APIKeyContains(v string) predicate.XunjiService {
+	return predicate.XunjiService(sql.FieldContains(FieldAPIKey, v))
+}
+
+// APIKeyHasPrefix applies the HasPrefix predicate on the "api_key" field.
+func APIKeyHasPrefix(v string) predicate.XunjiService {
+	return predicate.XunjiService(sql.FieldHasPrefix(FieldAPIKey, v))
+}
+
+// APIKeyHasSuffix applies the HasSuffix predicate on the "api_key" field.
+func APIKeyHasSuffix(v string) predicate.XunjiService {
+	return predicate.XunjiService(sql.FieldHasSuffix(FieldAPIKey, v))
+}
+
+// APIKeyIsNil applies the IsNil predicate on the "api_key" field.
+func APIKeyIsNil() predicate.XunjiService {
+	return predicate.XunjiService(sql.FieldIsNull(FieldAPIKey))
+}
+
+// APIKeyNotNil applies the NotNil predicate on the "api_key" field.
+func APIKeyNotNil() predicate.XunjiService {
+	return predicate.XunjiService(sql.FieldNotNull(FieldAPIKey))
+}
+
+// APIKeyEqualFold applies the EqualFold predicate on the "api_key" field.
+func APIKeyEqualFold(v string) predicate.XunjiService {
+	return predicate.XunjiService(sql.FieldEqualFold(FieldAPIKey, v))
+}
+
+// APIKeyContainsFold applies the ContainsFold predicate on the "api_key" field.
+func APIKeyContainsFold(v string) predicate.XunjiService {
+	return predicate.XunjiService(sql.FieldContainsFold(FieldAPIKey, v))
+}
+
+// HasAgent applies the HasEdge predicate on the "agent" edge.
+func HasAgent() predicate.XunjiService {
+	return predicate.XunjiService(func(s *sql.Selector) {
+		step := sqlgraph.NewStep(
+			sqlgraph.From(Table, FieldID),
+			sqlgraph.Edge(sqlgraph.M2O, true, AgentTable, AgentColumn),
+		)
+		sqlgraph.HasNeighbors(s, step)
+	})
+}
+
+// HasAgentWith applies the HasEdge predicate on the "agent" edge with a given conditions (other predicates).
+func HasAgentWith(preds ...predicate.Agent) predicate.XunjiService {
+	return predicate.XunjiService(func(s *sql.Selector) {
+		step := newAgentStep()
+		sqlgraph.HasNeighborsWith(s, step, func(s *sql.Selector) {
+			for _, p := range preds {
+				p(s)
+			}
+		})
+	})
+}
+
+// And groups predicates with the AND operator between them.
+func And(predicates ...predicate.XunjiService) predicate.XunjiService {
+	return predicate.XunjiService(sql.AndPredicates(predicates...))
+}
+
+// Or groups predicates with the OR operator between them.
+func Or(predicates ...predicate.XunjiService) predicate.XunjiService {
+	return predicate.XunjiService(sql.OrPredicates(predicates...))
+}
+
+// Not applies the not operator on the given predicate.
+func Not(p predicate.XunjiService) predicate.XunjiService {
+	return predicate.XunjiService(sql.NotPredicates(p))
+}

+ 172 - 0
ent/xunjiservice/xunjiservice.go

@@ -0,0 +1,172 @@
+// Code generated by ent, DO NOT EDIT.
+
+package xunjiservice
+
+import (
+	"time"
+
+	"entgo.io/ent"
+	"entgo.io/ent/dialect/sql"
+	"entgo.io/ent/dialect/sql/sqlgraph"
+)
+
+const (
+	// Label holds the string label denoting the xunjiservice type in the database.
+	Label = "xunji_service"
+	// 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"
+	// FieldXunjiID holds the string denoting the xunji_id field in the database.
+	FieldXunjiID = "xunji_id"
+	// FieldAgentID holds the string denoting the agent_id field in the database.
+	FieldAgentID = "agent_id"
+	// FieldOrganizationID holds the string denoting the organization_id field in the database.
+	FieldOrganizationID = "organization_id"
+	// FieldWxid holds the string denoting the wxid field in the database.
+	FieldWxid = "wxid"
+	// FieldAPIBase holds the string denoting the api_base field in the database.
+	FieldAPIBase = "api_base"
+	// FieldAPIKey holds the string denoting the api_key field in the database.
+	FieldAPIKey = "api_key"
+	// EdgeAgent holds the string denoting the agent edge name in mutations.
+	EdgeAgent = "agent"
+	// Table holds the table name of the xunjiservice in the database.
+	Table = "xunji_service"
+	// AgentTable is the table that holds the agent relation/edge.
+	AgentTable = "xunji_service"
+	// AgentInverseTable is the table name for the Agent entity.
+	// It exists in this package in order to avoid circular dependency with the "agent" package.
+	AgentInverseTable = "agent"
+	// AgentColumn is the table column denoting the agent relation/edge.
+	AgentColumn = "agent_id"
+)
+
+// Columns holds all SQL columns for xunjiservice fields.
+var Columns = []string{
+	FieldID,
+	FieldCreatedAt,
+	FieldUpdatedAt,
+	FieldStatus,
+	FieldDeletedAt,
+	FieldXunjiID,
+	FieldAgentID,
+	FieldOrganizationID,
+	FieldWxid,
+	FieldAPIBase,
+	FieldAPIKey,
+}
+
+// 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
+	// DefaultAgentID holds the default value on creation for the "agent_id" field.
+	DefaultAgentID uint64
+	// OrganizationIDValidator is a validator for the "organization_id" field. It is called by the builders before save.
+	OrganizationIDValidator func(uint64) error
+	// DefaultAPIBase holds the default value on creation for the "api_base" field.
+	DefaultAPIBase string
+	// DefaultAPIKey holds the default value on creation for the "api_key" field.
+	DefaultAPIKey string
+)
+
+// OrderOption defines the ordering options for the XunjiService 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()
+}
+
+// ByXunjiID orders the results by the xunji_id field.
+func ByXunjiID(opts ...sql.OrderTermOption) OrderOption {
+	return sql.OrderByField(FieldXunjiID, opts...).ToFunc()
+}
+
+// ByAgentID orders the results by the agent_id field.
+func ByAgentID(opts ...sql.OrderTermOption) OrderOption {
+	return sql.OrderByField(FieldAgentID, opts...).ToFunc()
+}
+
+// ByOrganizationID orders the results by the organization_id field.
+func ByOrganizationID(opts ...sql.OrderTermOption) OrderOption {
+	return sql.OrderByField(FieldOrganizationID, opts...).ToFunc()
+}
+
+// ByWxid orders the results by the wxid field.
+func ByWxid(opts ...sql.OrderTermOption) OrderOption {
+	return sql.OrderByField(FieldWxid, opts...).ToFunc()
+}
+
+// ByAPIBase orders the results by the api_base field.
+func ByAPIBase(opts ...sql.OrderTermOption) OrderOption {
+	return sql.OrderByField(FieldAPIBase, opts...).ToFunc()
+}
+
+// ByAPIKey orders the results by the api_key field.
+func ByAPIKey(opts ...sql.OrderTermOption) OrderOption {
+	return sql.OrderByField(FieldAPIKey, opts...).ToFunc()
+}
+
+// ByAgentField orders the results by agent field.
+func ByAgentField(field string, opts ...sql.OrderTermOption) OrderOption {
+	return func(s *sql.Selector) {
+		sqlgraph.OrderByNeighborTerms(s, newAgentStep(), sql.OrderByField(field, opts...))
+	}
+}
+func newAgentStep() *sqlgraph.Step {
+	return sqlgraph.NewStep(
+		sqlgraph.From(Table, FieldID),
+		sqlgraph.To(AgentInverseTable, FieldID),
+		sqlgraph.Edge(sqlgraph.M2O, true, AgentTable, AgentColumn),
+	)
+}

+ 1178 - 0
ent/xunjiservice_create.go

@@ -0,0 +1,1178 @@
+// Code generated by ent, DO NOT EDIT.
+
+package ent
+
+import (
+	"context"
+	"errors"
+	"fmt"
+	"time"
+	"wechat-api/ent/agent"
+	"wechat-api/ent/xunjiservice"
+
+	"entgo.io/ent/dialect/sql"
+	"entgo.io/ent/dialect/sql/sqlgraph"
+	"entgo.io/ent/schema/field"
+)
+
+// XunjiServiceCreate is the builder for creating a XunjiService entity.
+type XunjiServiceCreate struct {
+	config
+	mutation *XunjiServiceMutation
+	hooks    []Hook
+	conflict []sql.ConflictOption
+}
+
+// SetCreatedAt sets the "created_at" field.
+func (xsc *XunjiServiceCreate) SetCreatedAt(t time.Time) *XunjiServiceCreate {
+	xsc.mutation.SetCreatedAt(t)
+	return xsc
+}
+
+// SetNillableCreatedAt sets the "created_at" field if the given value is not nil.
+func (xsc *XunjiServiceCreate) SetNillableCreatedAt(t *time.Time) *XunjiServiceCreate {
+	if t != nil {
+		xsc.SetCreatedAt(*t)
+	}
+	return xsc
+}
+
+// SetUpdatedAt sets the "updated_at" field.
+func (xsc *XunjiServiceCreate) SetUpdatedAt(t time.Time) *XunjiServiceCreate {
+	xsc.mutation.SetUpdatedAt(t)
+	return xsc
+}
+
+// SetNillableUpdatedAt sets the "updated_at" field if the given value is not nil.
+func (xsc *XunjiServiceCreate) SetNillableUpdatedAt(t *time.Time) *XunjiServiceCreate {
+	if t != nil {
+		xsc.SetUpdatedAt(*t)
+	}
+	return xsc
+}
+
+// SetStatus sets the "status" field.
+func (xsc *XunjiServiceCreate) SetStatus(u uint8) *XunjiServiceCreate {
+	xsc.mutation.SetStatus(u)
+	return xsc
+}
+
+// SetNillableStatus sets the "status" field if the given value is not nil.
+func (xsc *XunjiServiceCreate) SetNillableStatus(u *uint8) *XunjiServiceCreate {
+	if u != nil {
+		xsc.SetStatus(*u)
+	}
+	return xsc
+}
+
+// SetDeletedAt sets the "deleted_at" field.
+func (xsc *XunjiServiceCreate) SetDeletedAt(t time.Time) *XunjiServiceCreate {
+	xsc.mutation.SetDeletedAt(t)
+	return xsc
+}
+
+// SetNillableDeletedAt sets the "deleted_at" field if the given value is not nil.
+func (xsc *XunjiServiceCreate) SetNillableDeletedAt(t *time.Time) *XunjiServiceCreate {
+	if t != nil {
+		xsc.SetDeletedAt(*t)
+	}
+	return xsc
+}
+
+// SetXunjiID sets the "xunji_id" field.
+func (xsc *XunjiServiceCreate) SetXunjiID(u uint64) *XunjiServiceCreate {
+	xsc.mutation.SetXunjiID(u)
+	return xsc
+}
+
+// SetAgentID sets the "agent_id" field.
+func (xsc *XunjiServiceCreate) SetAgentID(u uint64) *XunjiServiceCreate {
+	xsc.mutation.SetAgentID(u)
+	return xsc
+}
+
+// SetNillableAgentID sets the "agent_id" field if the given value is not nil.
+func (xsc *XunjiServiceCreate) SetNillableAgentID(u *uint64) *XunjiServiceCreate {
+	if u != nil {
+		xsc.SetAgentID(*u)
+	}
+	return xsc
+}
+
+// SetOrganizationID sets the "organization_id" field.
+func (xsc *XunjiServiceCreate) SetOrganizationID(u uint64) *XunjiServiceCreate {
+	xsc.mutation.SetOrganizationID(u)
+	return xsc
+}
+
+// SetWxid sets the "wxid" field.
+func (xsc *XunjiServiceCreate) SetWxid(s string) *XunjiServiceCreate {
+	xsc.mutation.SetWxid(s)
+	return xsc
+}
+
+// SetAPIBase sets the "api_base" field.
+func (xsc *XunjiServiceCreate) SetAPIBase(s string) *XunjiServiceCreate {
+	xsc.mutation.SetAPIBase(s)
+	return xsc
+}
+
+// SetNillableAPIBase sets the "api_base" field if the given value is not nil.
+func (xsc *XunjiServiceCreate) SetNillableAPIBase(s *string) *XunjiServiceCreate {
+	if s != nil {
+		xsc.SetAPIBase(*s)
+	}
+	return xsc
+}
+
+// SetAPIKey sets the "api_key" field.
+func (xsc *XunjiServiceCreate) SetAPIKey(s string) *XunjiServiceCreate {
+	xsc.mutation.SetAPIKey(s)
+	return xsc
+}
+
+// SetNillableAPIKey sets the "api_key" field if the given value is not nil.
+func (xsc *XunjiServiceCreate) SetNillableAPIKey(s *string) *XunjiServiceCreate {
+	if s != nil {
+		xsc.SetAPIKey(*s)
+	}
+	return xsc
+}
+
+// SetID sets the "id" field.
+func (xsc *XunjiServiceCreate) SetID(u uint64) *XunjiServiceCreate {
+	xsc.mutation.SetID(u)
+	return xsc
+}
+
+// SetAgent sets the "agent" edge to the Agent entity.
+func (xsc *XunjiServiceCreate) SetAgent(a *Agent) *XunjiServiceCreate {
+	return xsc.SetAgentID(a.ID)
+}
+
+// Mutation returns the XunjiServiceMutation object of the builder.
+func (xsc *XunjiServiceCreate) Mutation() *XunjiServiceMutation {
+	return xsc.mutation
+}
+
+// Save creates the XunjiService in the database.
+func (xsc *XunjiServiceCreate) Save(ctx context.Context) (*XunjiService, error) {
+	if err := xsc.defaults(); err != nil {
+		return nil, err
+	}
+	return withHooks(ctx, xsc.sqlSave, xsc.mutation, xsc.hooks)
+}
+
+// SaveX calls Save and panics if Save returns an error.
+func (xsc *XunjiServiceCreate) SaveX(ctx context.Context) *XunjiService {
+	v, err := xsc.Save(ctx)
+	if err != nil {
+		panic(err)
+	}
+	return v
+}
+
+// Exec executes the query.
+func (xsc *XunjiServiceCreate) Exec(ctx context.Context) error {
+	_, err := xsc.Save(ctx)
+	return err
+}
+
+// ExecX is like Exec, but panics if an error occurs.
+func (xsc *XunjiServiceCreate) ExecX(ctx context.Context) {
+	if err := xsc.Exec(ctx); err != nil {
+		panic(err)
+	}
+}
+
+// defaults sets the default values of the builder before save.
+func (xsc *XunjiServiceCreate) defaults() error {
+	if _, ok := xsc.mutation.CreatedAt(); !ok {
+		if xunjiservice.DefaultCreatedAt == nil {
+			return fmt.Errorf("ent: uninitialized xunjiservice.DefaultCreatedAt (forgotten import ent/runtime?)")
+		}
+		v := xunjiservice.DefaultCreatedAt()
+		xsc.mutation.SetCreatedAt(v)
+	}
+	if _, ok := xsc.mutation.UpdatedAt(); !ok {
+		if xunjiservice.DefaultUpdatedAt == nil {
+			return fmt.Errorf("ent: uninitialized xunjiservice.DefaultUpdatedAt (forgotten import ent/runtime?)")
+		}
+		v := xunjiservice.DefaultUpdatedAt()
+		xsc.mutation.SetUpdatedAt(v)
+	}
+	if _, ok := xsc.mutation.Status(); !ok {
+		v := xunjiservice.DefaultStatus
+		xsc.mutation.SetStatus(v)
+	}
+	if _, ok := xsc.mutation.AgentID(); !ok {
+		v := xunjiservice.DefaultAgentID
+		xsc.mutation.SetAgentID(v)
+	}
+	if _, ok := xsc.mutation.APIBase(); !ok {
+		v := xunjiservice.DefaultAPIBase
+		xsc.mutation.SetAPIBase(v)
+	}
+	if _, ok := xsc.mutation.APIKey(); !ok {
+		v := xunjiservice.DefaultAPIKey
+		xsc.mutation.SetAPIKey(v)
+	}
+	return nil
+}
+
+// check runs all checks and user-defined validators on the builder.
+func (xsc *XunjiServiceCreate) check() error {
+	if _, ok := xsc.mutation.CreatedAt(); !ok {
+		return &ValidationError{Name: "created_at", err: errors.New(`ent: missing required field "XunjiService.created_at"`)}
+	}
+	if _, ok := xsc.mutation.UpdatedAt(); !ok {
+		return &ValidationError{Name: "updated_at", err: errors.New(`ent: missing required field "XunjiService.updated_at"`)}
+	}
+	if _, ok := xsc.mutation.XunjiID(); !ok {
+		return &ValidationError{Name: "xunji_id", err: errors.New(`ent: missing required field "XunjiService.xunji_id"`)}
+	}
+	if _, ok := xsc.mutation.AgentID(); !ok {
+		return &ValidationError{Name: "agent_id", err: errors.New(`ent: missing required field "XunjiService.agent_id"`)}
+	}
+	if _, ok := xsc.mutation.OrganizationID(); !ok {
+		return &ValidationError{Name: "organization_id", err: errors.New(`ent: missing required field "XunjiService.organization_id"`)}
+	}
+	if v, ok := xsc.mutation.OrganizationID(); ok {
+		if err := xunjiservice.OrganizationIDValidator(v); err != nil {
+			return &ValidationError{Name: "organization_id", err: fmt.Errorf(`ent: validator failed for field "XunjiService.organization_id": %w`, err)}
+		}
+	}
+	if _, ok := xsc.mutation.Wxid(); !ok {
+		return &ValidationError{Name: "wxid", err: errors.New(`ent: missing required field "XunjiService.wxid"`)}
+	}
+	if _, ok := xsc.mutation.AgentID(); !ok {
+		return &ValidationError{Name: "agent", err: errors.New(`ent: missing required edge "XunjiService.agent"`)}
+	}
+	return nil
+}
+
+func (xsc *XunjiServiceCreate) sqlSave(ctx context.Context) (*XunjiService, error) {
+	if err := xsc.check(); err != nil {
+		return nil, err
+	}
+	_node, _spec := xsc.createSpec()
+	if err := sqlgraph.CreateNode(ctx, xsc.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)
+	}
+	xsc.mutation.id = &_node.ID
+	xsc.mutation.done = true
+	return _node, nil
+}
+
+func (xsc *XunjiServiceCreate) createSpec() (*XunjiService, *sqlgraph.CreateSpec) {
+	var (
+		_node = &XunjiService{config: xsc.config}
+		_spec = sqlgraph.NewCreateSpec(xunjiservice.Table, sqlgraph.NewFieldSpec(xunjiservice.FieldID, field.TypeUint64))
+	)
+	_spec.OnConflict = xsc.conflict
+	if id, ok := xsc.mutation.ID(); ok {
+		_node.ID = id
+		_spec.ID.Value = id
+	}
+	if value, ok := xsc.mutation.CreatedAt(); ok {
+		_spec.SetField(xunjiservice.FieldCreatedAt, field.TypeTime, value)
+		_node.CreatedAt = value
+	}
+	if value, ok := xsc.mutation.UpdatedAt(); ok {
+		_spec.SetField(xunjiservice.FieldUpdatedAt, field.TypeTime, value)
+		_node.UpdatedAt = value
+	}
+	if value, ok := xsc.mutation.Status(); ok {
+		_spec.SetField(xunjiservice.FieldStatus, field.TypeUint8, value)
+		_node.Status = value
+	}
+	if value, ok := xsc.mutation.DeletedAt(); ok {
+		_spec.SetField(xunjiservice.FieldDeletedAt, field.TypeTime, value)
+		_node.DeletedAt = value
+	}
+	if value, ok := xsc.mutation.XunjiID(); ok {
+		_spec.SetField(xunjiservice.FieldXunjiID, field.TypeUint64, value)
+		_node.XunjiID = value
+	}
+	if value, ok := xsc.mutation.OrganizationID(); ok {
+		_spec.SetField(xunjiservice.FieldOrganizationID, field.TypeUint64, value)
+		_node.OrganizationID = value
+	}
+	if value, ok := xsc.mutation.Wxid(); ok {
+		_spec.SetField(xunjiservice.FieldWxid, field.TypeString, value)
+		_node.Wxid = value
+	}
+	if value, ok := xsc.mutation.APIBase(); ok {
+		_spec.SetField(xunjiservice.FieldAPIBase, field.TypeString, value)
+		_node.APIBase = value
+	}
+	if value, ok := xsc.mutation.APIKey(); ok {
+		_spec.SetField(xunjiservice.FieldAPIKey, field.TypeString, value)
+		_node.APIKey = value
+	}
+	if nodes := xsc.mutation.AgentIDs(); len(nodes) > 0 {
+		edge := &sqlgraph.EdgeSpec{
+			Rel:     sqlgraph.M2O,
+			Inverse: true,
+			Table:   xunjiservice.AgentTable,
+			Columns: []string{xunjiservice.AgentColumn},
+			Bidi:    false,
+			Target: &sqlgraph.EdgeTarget{
+				IDSpec: sqlgraph.NewFieldSpec(agent.FieldID, field.TypeUint64),
+			},
+		}
+		for _, k := range nodes {
+			edge.Target.Nodes = append(edge.Target.Nodes, k)
+		}
+		_node.AgentID = nodes[0]
+		_spec.Edges = append(_spec.Edges, edge)
+	}
+	return _node, _spec
+}
+
+// OnConflict allows configuring the `ON CONFLICT` / `ON DUPLICATE KEY` clause
+// of the `INSERT` statement. For example:
+//
+//	client.XunjiService.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.XunjiServiceUpsert) {
+//			SetCreatedAt(v+v).
+//		}).
+//		Exec(ctx)
+func (xsc *XunjiServiceCreate) OnConflict(opts ...sql.ConflictOption) *XunjiServiceUpsertOne {
+	xsc.conflict = opts
+	return &XunjiServiceUpsertOne{
+		create: xsc,
+	}
+}
+
+// OnConflictColumns calls `OnConflict` and configures the columns
+// as conflict target. Using this option is equivalent to using:
+//
+//	client.XunjiService.Create().
+//		OnConflict(sql.ConflictColumns(columns...)).
+//		Exec(ctx)
+func (xsc *XunjiServiceCreate) OnConflictColumns(columns ...string) *XunjiServiceUpsertOne {
+	xsc.conflict = append(xsc.conflict, sql.ConflictColumns(columns...))
+	return &XunjiServiceUpsertOne{
+		create: xsc,
+	}
+}
+
+type (
+	// XunjiServiceUpsertOne is the builder for "upsert"-ing
+	//  one XunjiService node.
+	XunjiServiceUpsertOne struct {
+		create *XunjiServiceCreate
+	}
+
+	// XunjiServiceUpsert is the "OnConflict" setter.
+	XunjiServiceUpsert struct {
+		*sql.UpdateSet
+	}
+)
+
+// SetUpdatedAt sets the "updated_at" field.
+func (u *XunjiServiceUpsert) SetUpdatedAt(v time.Time) *XunjiServiceUpsert {
+	u.Set(xunjiservice.FieldUpdatedAt, v)
+	return u
+}
+
+// UpdateUpdatedAt sets the "updated_at" field to the value that was provided on create.
+func (u *XunjiServiceUpsert) UpdateUpdatedAt() *XunjiServiceUpsert {
+	u.SetExcluded(xunjiservice.FieldUpdatedAt)
+	return u
+}
+
+// SetStatus sets the "status" field.
+func (u *XunjiServiceUpsert) SetStatus(v uint8) *XunjiServiceUpsert {
+	u.Set(xunjiservice.FieldStatus, v)
+	return u
+}
+
+// UpdateStatus sets the "status" field to the value that was provided on create.
+func (u *XunjiServiceUpsert) UpdateStatus() *XunjiServiceUpsert {
+	u.SetExcluded(xunjiservice.FieldStatus)
+	return u
+}
+
+// AddStatus adds v to the "status" field.
+func (u *XunjiServiceUpsert) AddStatus(v uint8) *XunjiServiceUpsert {
+	u.Add(xunjiservice.FieldStatus, v)
+	return u
+}
+
+// ClearStatus clears the value of the "status" field.
+func (u *XunjiServiceUpsert) ClearStatus() *XunjiServiceUpsert {
+	u.SetNull(xunjiservice.FieldStatus)
+	return u
+}
+
+// SetDeletedAt sets the "deleted_at" field.
+func (u *XunjiServiceUpsert) SetDeletedAt(v time.Time) *XunjiServiceUpsert {
+	u.Set(xunjiservice.FieldDeletedAt, v)
+	return u
+}
+
+// UpdateDeletedAt sets the "deleted_at" field to the value that was provided on create.
+func (u *XunjiServiceUpsert) UpdateDeletedAt() *XunjiServiceUpsert {
+	u.SetExcluded(xunjiservice.FieldDeletedAt)
+	return u
+}
+
+// ClearDeletedAt clears the value of the "deleted_at" field.
+func (u *XunjiServiceUpsert) ClearDeletedAt() *XunjiServiceUpsert {
+	u.SetNull(xunjiservice.FieldDeletedAt)
+	return u
+}
+
+// SetXunjiID sets the "xunji_id" field.
+func (u *XunjiServiceUpsert) SetXunjiID(v uint64) *XunjiServiceUpsert {
+	u.Set(xunjiservice.FieldXunjiID, v)
+	return u
+}
+
+// UpdateXunjiID sets the "xunji_id" field to the value that was provided on create.
+func (u *XunjiServiceUpsert) UpdateXunjiID() *XunjiServiceUpsert {
+	u.SetExcluded(xunjiservice.FieldXunjiID)
+	return u
+}
+
+// AddXunjiID adds v to the "xunji_id" field.
+func (u *XunjiServiceUpsert) AddXunjiID(v uint64) *XunjiServiceUpsert {
+	u.Add(xunjiservice.FieldXunjiID, v)
+	return u
+}
+
+// SetAgentID sets the "agent_id" field.
+func (u *XunjiServiceUpsert) SetAgentID(v uint64) *XunjiServiceUpsert {
+	u.Set(xunjiservice.FieldAgentID, v)
+	return u
+}
+
+// UpdateAgentID sets the "agent_id" field to the value that was provided on create.
+func (u *XunjiServiceUpsert) UpdateAgentID() *XunjiServiceUpsert {
+	u.SetExcluded(xunjiservice.FieldAgentID)
+	return u
+}
+
+// SetOrganizationID sets the "organization_id" field.
+func (u *XunjiServiceUpsert) SetOrganizationID(v uint64) *XunjiServiceUpsert {
+	u.Set(xunjiservice.FieldOrganizationID, v)
+	return u
+}
+
+// UpdateOrganizationID sets the "organization_id" field to the value that was provided on create.
+func (u *XunjiServiceUpsert) UpdateOrganizationID() *XunjiServiceUpsert {
+	u.SetExcluded(xunjiservice.FieldOrganizationID)
+	return u
+}
+
+// AddOrganizationID adds v to the "organization_id" field.
+func (u *XunjiServiceUpsert) AddOrganizationID(v uint64) *XunjiServiceUpsert {
+	u.Add(xunjiservice.FieldOrganizationID, v)
+	return u
+}
+
+// SetWxid sets the "wxid" field.
+func (u *XunjiServiceUpsert) SetWxid(v string) *XunjiServiceUpsert {
+	u.Set(xunjiservice.FieldWxid, v)
+	return u
+}
+
+// UpdateWxid sets the "wxid" field to the value that was provided on create.
+func (u *XunjiServiceUpsert) UpdateWxid() *XunjiServiceUpsert {
+	u.SetExcluded(xunjiservice.FieldWxid)
+	return u
+}
+
+// SetAPIBase sets the "api_base" field.
+func (u *XunjiServiceUpsert) SetAPIBase(v string) *XunjiServiceUpsert {
+	u.Set(xunjiservice.FieldAPIBase, v)
+	return u
+}
+
+// UpdateAPIBase sets the "api_base" field to the value that was provided on create.
+func (u *XunjiServiceUpsert) UpdateAPIBase() *XunjiServiceUpsert {
+	u.SetExcluded(xunjiservice.FieldAPIBase)
+	return u
+}
+
+// ClearAPIBase clears the value of the "api_base" field.
+func (u *XunjiServiceUpsert) ClearAPIBase() *XunjiServiceUpsert {
+	u.SetNull(xunjiservice.FieldAPIBase)
+	return u
+}
+
+// SetAPIKey sets the "api_key" field.
+func (u *XunjiServiceUpsert) SetAPIKey(v string) *XunjiServiceUpsert {
+	u.Set(xunjiservice.FieldAPIKey, v)
+	return u
+}
+
+// UpdateAPIKey sets the "api_key" field to the value that was provided on create.
+func (u *XunjiServiceUpsert) UpdateAPIKey() *XunjiServiceUpsert {
+	u.SetExcluded(xunjiservice.FieldAPIKey)
+	return u
+}
+
+// ClearAPIKey clears the value of the "api_key" field.
+func (u *XunjiServiceUpsert) ClearAPIKey() *XunjiServiceUpsert {
+	u.SetNull(xunjiservice.FieldAPIKey)
+	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.XunjiService.Create().
+//		OnConflict(
+//			sql.ResolveWithNewValues(),
+//			sql.ResolveWith(func(u *sql.UpdateSet) {
+//				u.SetIgnore(xunjiservice.FieldID)
+//			}),
+//		).
+//		Exec(ctx)
+func (u *XunjiServiceUpsertOne) UpdateNewValues() *XunjiServiceUpsertOne {
+	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(xunjiservice.FieldID)
+		}
+		if _, exists := u.create.mutation.CreatedAt(); exists {
+			s.SetIgnore(xunjiservice.FieldCreatedAt)
+		}
+	}))
+	return u
+}
+
+// Ignore sets each column to itself in case of conflict.
+// Using this option is equivalent to using:
+//
+//	client.XunjiService.Create().
+//	    OnConflict(sql.ResolveWithIgnore()).
+//	    Exec(ctx)
+func (u *XunjiServiceUpsertOne) Ignore() *XunjiServiceUpsertOne {
+	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 *XunjiServiceUpsertOne) DoNothing() *XunjiServiceUpsertOne {
+	u.create.conflict = append(u.create.conflict, sql.DoNothing())
+	return u
+}
+
+// Update allows overriding fields `UPDATE` values. See the XunjiServiceCreate.OnConflict
+// documentation for more info.
+func (u *XunjiServiceUpsertOne) Update(set func(*XunjiServiceUpsert)) *XunjiServiceUpsertOne {
+	u.create.conflict = append(u.create.conflict, sql.ResolveWith(func(update *sql.UpdateSet) {
+		set(&XunjiServiceUpsert{UpdateSet: update})
+	}))
+	return u
+}
+
+// SetUpdatedAt sets the "updated_at" field.
+func (u *XunjiServiceUpsertOne) SetUpdatedAt(v time.Time) *XunjiServiceUpsertOne {
+	return u.Update(func(s *XunjiServiceUpsert) {
+		s.SetUpdatedAt(v)
+	})
+}
+
+// UpdateUpdatedAt sets the "updated_at" field to the value that was provided on create.
+func (u *XunjiServiceUpsertOne) UpdateUpdatedAt() *XunjiServiceUpsertOne {
+	return u.Update(func(s *XunjiServiceUpsert) {
+		s.UpdateUpdatedAt()
+	})
+}
+
+// SetStatus sets the "status" field.
+func (u *XunjiServiceUpsertOne) SetStatus(v uint8) *XunjiServiceUpsertOne {
+	return u.Update(func(s *XunjiServiceUpsert) {
+		s.SetStatus(v)
+	})
+}
+
+// AddStatus adds v to the "status" field.
+func (u *XunjiServiceUpsertOne) AddStatus(v uint8) *XunjiServiceUpsertOne {
+	return u.Update(func(s *XunjiServiceUpsert) {
+		s.AddStatus(v)
+	})
+}
+
+// UpdateStatus sets the "status" field to the value that was provided on create.
+func (u *XunjiServiceUpsertOne) UpdateStatus() *XunjiServiceUpsertOne {
+	return u.Update(func(s *XunjiServiceUpsert) {
+		s.UpdateStatus()
+	})
+}
+
+// ClearStatus clears the value of the "status" field.
+func (u *XunjiServiceUpsertOne) ClearStatus() *XunjiServiceUpsertOne {
+	return u.Update(func(s *XunjiServiceUpsert) {
+		s.ClearStatus()
+	})
+}
+
+// SetDeletedAt sets the "deleted_at" field.
+func (u *XunjiServiceUpsertOne) SetDeletedAt(v time.Time) *XunjiServiceUpsertOne {
+	return u.Update(func(s *XunjiServiceUpsert) {
+		s.SetDeletedAt(v)
+	})
+}
+
+// UpdateDeletedAt sets the "deleted_at" field to the value that was provided on create.
+func (u *XunjiServiceUpsertOne) UpdateDeletedAt() *XunjiServiceUpsertOne {
+	return u.Update(func(s *XunjiServiceUpsert) {
+		s.UpdateDeletedAt()
+	})
+}
+
+// ClearDeletedAt clears the value of the "deleted_at" field.
+func (u *XunjiServiceUpsertOne) ClearDeletedAt() *XunjiServiceUpsertOne {
+	return u.Update(func(s *XunjiServiceUpsert) {
+		s.ClearDeletedAt()
+	})
+}
+
+// SetXunjiID sets the "xunji_id" field.
+func (u *XunjiServiceUpsertOne) SetXunjiID(v uint64) *XunjiServiceUpsertOne {
+	return u.Update(func(s *XunjiServiceUpsert) {
+		s.SetXunjiID(v)
+	})
+}
+
+// AddXunjiID adds v to the "xunji_id" field.
+func (u *XunjiServiceUpsertOne) AddXunjiID(v uint64) *XunjiServiceUpsertOne {
+	return u.Update(func(s *XunjiServiceUpsert) {
+		s.AddXunjiID(v)
+	})
+}
+
+// UpdateXunjiID sets the "xunji_id" field to the value that was provided on create.
+func (u *XunjiServiceUpsertOne) UpdateXunjiID() *XunjiServiceUpsertOne {
+	return u.Update(func(s *XunjiServiceUpsert) {
+		s.UpdateXunjiID()
+	})
+}
+
+// SetAgentID sets the "agent_id" field.
+func (u *XunjiServiceUpsertOne) SetAgentID(v uint64) *XunjiServiceUpsertOne {
+	return u.Update(func(s *XunjiServiceUpsert) {
+		s.SetAgentID(v)
+	})
+}
+
+// UpdateAgentID sets the "agent_id" field to the value that was provided on create.
+func (u *XunjiServiceUpsertOne) UpdateAgentID() *XunjiServiceUpsertOne {
+	return u.Update(func(s *XunjiServiceUpsert) {
+		s.UpdateAgentID()
+	})
+}
+
+// SetOrganizationID sets the "organization_id" field.
+func (u *XunjiServiceUpsertOne) SetOrganizationID(v uint64) *XunjiServiceUpsertOne {
+	return u.Update(func(s *XunjiServiceUpsert) {
+		s.SetOrganizationID(v)
+	})
+}
+
+// AddOrganizationID adds v to the "organization_id" field.
+func (u *XunjiServiceUpsertOne) AddOrganizationID(v uint64) *XunjiServiceUpsertOne {
+	return u.Update(func(s *XunjiServiceUpsert) {
+		s.AddOrganizationID(v)
+	})
+}
+
+// UpdateOrganizationID sets the "organization_id" field to the value that was provided on create.
+func (u *XunjiServiceUpsertOne) UpdateOrganizationID() *XunjiServiceUpsertOne {
+	return u.Update(func(s *XunjiServiceUpsert) {
+		s.UpdateOrganizationID()
+	})
+}
+
+// SetWxid sets the "wxid" field.
+func (u *XunjiServiceUpsertOne) SetWxid(v string) *XunjiServiceUpsertOne {
+	return u.Update(func(s *XunjiServiceUpsert) {
+		s.SetWxid(v)
+	})
+}
+
+// UpdateWxid sets the "wxid" field to the value that was provided on create.
+func (u *XunjiServiceUpsertOne) UpdateWxid() *XunjiServiceUpsertOne {
+	return u.Update(func(s *XunjiServiceUpsert) {
+		s.UpdateWxid()
+	})
+}
+
+// SetAPIBase sets the "api_base" field.
+func (u *XunjiServiceUpsertOne) SetAPIBase(v string) *XunjiServiceUpsertOne {
+	return u.Update(func(s *XunjiServiceUpsert) {
+		s.SetAPIBase(v)
+	})
+}
+
+// UpdateAPIBase sets the "api_base" field to the value that was provided on create.
+func (u *XunjiServiceUpsertOne) UpdateAPIBase() *XunjiServiceUpsertOne {
+	return u.Update(func(s *XunjiServiceUpsert) {
+		s.UpdateAPIBase()
+	})
+}
+
+// ClearAPIBase clears the value of the "api_base" field.
+func (u *XunjiServiceUpsertOne) ClearAPIBase() *XunjiServiceUpsertOne {
+	return u.Update(func(s *XunjiServiceUpsert) {
+		s.ClearAPIBase()
+	})
+}
+
+// SetAPIKey sets the "api_key" field.
+func (u *XunjiServiceUpsertOne) SetAPIKey(v string) *XunjiServiceUpsertOne {
+	return u.Update(func(s *XunjiServiceUpsert) {
+		s.SetAPIKey(v)
+	})
+}
+
+// UpdateAPIKey sets the "api_key" field to the value that was provided on create.
+func (u *XunjiServiceUpsertOne) UpdateAPIKey() *XunjiServiceUpsertOne {
+	return u.Update(func(s *XunjiServiceUpsert) {
+		s.UpdateAPIKey()
+	})
+}
+
+// ClearAPIKey clears the value of the "api_key" field.
+func (u *XunjiServiceUpsertOne) ClearAPIKey() *XunjiServiceUpsertOne {
+	return u.Update(func(s *XunjiServiceUpsert) {
+		s.ClearAPIKey()
+	})
+}
+
+// Exec executes the query.
+func (u *XunjiServiceUpsertOne) Exec(ctx context.Context) error {
+	if len(u.create.conflict) == 0 {
+		return errors.New("ent: missing options for XunjiServiceCreate.OnConflict")
+	}
+	return u.create.Exec(ctx)
+}
+
+// ExecX is like Exec, but panics if an error occurs.
+func (u *XunjiServiceUpsertOne) 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 *XunjiServiceUpsertOne) 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 *XunjiServiceUpsertOne) IDX(ctx context.Context) uint64 {
+	id, err := u.ID(ctx)
+	if err != nil {
+		panic(err)
+	}
+	return id
+}
+
+// XunjiServiceCreateBulk is the builder for creating many XunjiService entities in bulk.
+type XunjiServiceCreateBulk struct {
+	config
+	err      error
+	builders []*XunjiServiceCreate
+	conflict []sql.ConflictOption
+}
+
+// Save creates the XunjiService entities in the database.
+func (xscb *XunjiServiceCreateBulk) Save(ctx context.Context) ([]*XunjiService, error) {
+	if xscb.err != nil {
+		return nil, xscb.err
+	}
+	specs := make([]*sqlgraph.CreateSpec, len(xscb.builders))
+	nodes := make([]*XunjiService, len(xscb.builders))
+	mutators := make([]Mutator, len(xscb.builders))
+	for i := range xscb.builders {
+		func(i int, root context.Context) {
+			builder := xscb.builders[i]
+			builder.defaults()
+			var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) {
+				mutation, ok := m.(*XunjiServiceMutation)
+				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, xscb.builders[i+1].mutation)
+				} else {
+					spec := &sqlgraph.BatchCreateSpec{Nodes: specs}
+					spec.OnConflict = xscb.conflict
+					// Invoke the actual operation on the latest mutation in the chain.
+					if err = sqlgraph.BatchCreate(ctx, xscb.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, xscb.builders[0].mutation); err != nil {
+			return nil, err
+		}
+	}
+	return nodes, nil
+}
+
+// SaveX is like Save, but panics if an error occurs.
+func (xscb *XunjiServiceCreateBulk) SaveX(ctx context.Context) []*XunjiService {
+	v, err := xscb.Save(ctx)
+	if err != nil {
+		panic(err)
+	}
+	return v
+}
+
+// Exec executes the query.
+func (xscb *XunjiServiceCreateBulk) Exec(ctx context.Context) error {
+	_, err := xscb.Save(ctx)
+	return err
+}
+
+// ExecX is like Exec, but panics if an error occurs.
+func (xscb *XunjiServiceCreateBulk) ExecX(ctx context.Context) {
+	if err := xscb.Exec(ctx); err != nil {
+		panic(err)
+	}
+}
+
+// OnConflict allows configuring the `ON CONFLICT` / `ON DUPLICATE KEY` clause
+// of the `INSERT` statement. For example:
+//
+//	client.XunjiService.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.XunjiServiceUpsert) {
+//			SetCreatedAt(v+v).
+//		}).
+//		Exec(ctx)
+func (xscb *XunjiServiceCreateBulk) OnConflict(opts ...sql.ConflictOption) *XunjiServiceUpsertBulk {
+	xscb.conflict = opts
+	return &XunjiServiceUpsertBulk{
+		create: xscb,
+	}
+}
+
+// OnConflictColumns calls `OnConflict` and configures the columns
+// as conflict target. Using this option is equivalent to using:
+//
+//	client.XunjiService.Create().
+//		OnConflict(sql.ConflictColumns(columns...)).
+//		Exec(ctx)
+func (xscb *XunjiServiceCreateBulk) OnConflictColumns(columns ...string) *XunjiServiceUpsertBulk {
+	xscb.conflict = append(xscb.conflict, sql.ConflictColumns(columns...))
+	return &XunjiServiceUpsertBulk{
+		create: xscb,
+	}
+}
+
+// XunjiServiceUpsertBulk is the builder for "upsert"-ing
+// a bulk of XunjiService nodes.
+type XunjiServiceUpsertBulk struct {
+	create *XunjiServiceCreateBulk
+}
+
+// UpdateNewValues updates the mutable fields using the new values that
+// were set on create. Using this option is equivalent to using:
+//
+//	client.XunjiService.Create().
+//		OnConflict(
+//			sql.ResolveWithNewValues(),
+//			sql.ResolveWith(func(u *sql.UpdateSet) {
+//				u.SetIgnore(xunjiservice.FieldID)
+//			}),
+//		).
+//		Exec(ctx)
+func (u *XunjiServiceUpsertBulk) UpdateNewValues() *XunjiServiceUpsertBulk {
+	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(xunjiservice.FieldID)
+			}
+			if _, exists := b.mutation.CreatedAt(); exists {
+				s.SetIgnore(xunjiservice.FieldCreatedAt)
+			}
+		}
+	}))
+	return u
+}
+
+// Ignore sets each column to itself in case of conflict.
+// Using this option is equivalent to using:
+//
+//	client.XunjiService.Create().
+//		OnConflict(sql.ResolveWithIgnore()).
+//		Exec(ctx)
+func (u *XunjiServiceUpsertBulk) Ignore() *XunjiServiceUpsertBulk {
+	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 *XunjiServiceUpsertBulk) DoNothing() *XunjiServiceUpsertBulk {
+	u.create.conflict = append(u.create.conflict, sql.DoNothing())
+	return u
+}
+
+// Update allows overriding fields `UPDATE` values. See the XunjiServiceCreateBulk.OnConflict
+// documentation for more info.
+func (u *XunjiServiceUpsertBulk) Update(set func(*XunjiServiceUpsert)) *XunjiServiceUpsertBulk {
+	u.create.conflict = append(u.create.conflict, sql.ResolveWith(func(update *sql.UpdateSet) {
+		set(&XunjiServiceUpsert{UpdateSet: update})
+	}))
+	return u
+}
+
+// SetUpdatedAt sets the "updated_at" field.
+func (u *XunjiServiceUpsertBulk) SetUpdatedAt(v time.Time) *XunjiServiceUpsertBulk {
+	return u.Update(func(s *XunjiServiceUpsert) {
+		s.SetUpdatedAt(v)
+	})
+}
+
+// UpdateUpdatedAt sets the "updated_at" field to the value that was provided on create.
+func (u *XunjiServiceUpsertBulk) UpdateUpdatedAt() *XunjiServiceUpsertBulk {
+	return u.Update(func(s *XunjiServiceUpsert) {
+		s.UpdateUpdatedAt()
+	})
+}
+
+// SetStatus sets the "status" field.
+func (u *XunjiServiceUpsertBulk) SetStatus(v uint8) *XunjiServiceUpsertBulk {
+	return u.Update(func(s *XunjiServiceUpsert) {
+		s.SetStatus(v)
+	})
+}
+
+// AddStatus adds v to the "status" field.
+func (u *XunjiServiceUpsertBulk) AddStatus(v uint8) *XunjiServiceUpsertBulk {
+	return u.Update(func(s *XunjiServiceUpsert) {
+		s.AddStatus(v)
+	})
+}
+
+// UpdateStatus sets the "status" field to the value that was provided on create.
+func (u *XunjiServiceUpsertBulk) UpdateStatus() *XunjiServiceUpsertBulk {
+	return u.Update(func(s *XunjiServiceUpsert) {
+		s.UpdateStatus()
+	})
+}
+
+// ClearStatus clears the value of the "status" field.
+func (u *XunjiServiceUpsertBulk) ClearStatus() *XunjiServiceUpsertBulk {
+	return u.Update(func(s *XunjiServiceUpsert) {
+		s.ClearStatus()
+	})
+}
+
+// SetDeletedAt sets the "deleted_at" field.
+func (u *XunjiServiceUpsertBulk) SetDeletedAt(v time.Time) *XunjiServiceUpsertBulk {
+	return u.Update(func(s *XunjiServiceUpsert) {
+		s.SetDeletedAt(v)
+	})
+}
+
+// UpdateDeletedAt sets the "deleted_at" field to the value that was provided on create.
+func (u *XunjiServiceUpsertBulk) UpdateDeletedAt() *XunjiServiceUpsertBulk {
+	return u.Update(func(s *XunjiServiceUpsert) {
+		s.UpdateDeletedAt()
+	})
+}
+
+// ClearDeletedAt clears the value of the "deleted_at" field.
+func (u *XunjiServiceUpsertBulk) ClearDeletedAt() *XunjiServiceUpsertBulk {
+	return u.Update(func(s *XunjiServiceUpsert) {
+		s.ClearDeletedAt()
+	})
+}
+
+// SetXunjiID sets the "xunji_id" field.
+func (u *XunjiServiceUpsertBulk) SetXunjiID(v uint64) *XunjiServiceUpsertBulk {
+	return u.Update(func(s *XunjiServiceUpsert) {
+		s.SetXunjiID(v)
+	})
+}
+
+// AddXunjiID adds v to the "xunji_id" field.
+func (u *XunjiServiceUpsertBulk) AddXunjiID(v uint64) *XunjiServiceUpsertBulk {
+	return u.Update(func(s *XunjiServiceUpsert) {
+		s.AddXunjiID(v)
+	})
+}
+
+// UpdateXunjiID sets the "xunji_id" field to the value that was provided on create.
+func (u *XunjiServiceUpsertBulk) UpdateXunjiID() *XunjiServiceUpsertBulk {
+	return u.Update(func(s *XunjiServiceUpsert) {
+		s.UpdateXunjiID()
+	})
+}
+
+// SetAgentID sets the "agent_id" field.
+func (u *XunjiServiceUpsertBulk) SetAgentID(v uint64) *XunjiServiceUpsertBulk {
+	return u.Update(func(s *XunjiServiceUpsert) {
+		s.SetAgentID(v)
+	})
+}
+
+// UpdateAgentID sets the "agent_id" field to the value that was provided on create.
+func (u *XunjiServiceUpsertBulk) UpdateAgentID() *XunjiServiceUpsertBulk {
+	return u.Update(func(s *XunjiServiceUpsert) {
+		s.UpdateAgentID()
+	})
+}
+
+// SetOrganizationID sets the "organization_id" field.
+func (u *XunjiServiceUpsertBulk) SetOrganizationID(v uint64) *XunjiServiceUpsertBulk {
+	return u.Update(func(s *XunjiServiceUpsert) {
+		s.SetOrganizationID(v)
+	})
+}
+
+// AddOrganizationID adds v to the "organization_id" field.
+func (u *XunjiServiceUpsertBulk) AddOrganizationID(v uint64) *XunjiServiceUpsertBulk {
+	return u.Update(func(s *XunjiServiceUpsert) {
+		s.AddOrganizationID(v)
+	})
+}
+
+// UpdateOrganizationID sets the "organization_id" field to the value that was provided on create.
+func (u *XunjiServiceUpsertBulk) UpdateOrganizationID() *XunjiServiceUpsertBulk {
+	return u.Update(func(s *XunjiServiceUpsert) {
+		s.UpdateOrganizationID()
+	})
+}
+
+// SetWxid sets the "wxid" field.
+func (u *XunjiServiceUpsertBulk) SetWxid(v string) *XunjiServiceUpsertBulk {
+	return u.Update(func(s *XunjiServiceUpsert) {
+		s.SetWxid(v)
+	})
+}
+
+// UpdateWxid sets the "wxid" field to the value that was provided on create.
+func (u *XunjiServiceUpsertBulk) UpdateWxid() *XunjiServiceUpsertBulk {
+	return u.Update(func(s *XunjiServiceUpsert) {
+		s.UpdateWxid()
+	})
+}
+
+// SetAPIBase sets the "api_base" field.
+func (u *XunjiServiceUpsertBulk) SetAPIBase(v string) *XunjiServiceUpsertBulk {
+	return u.Update(func(s *XunjiServiceUpsert) {
+		s.SetAPIBase(v)
+	})
+}
+
+// UpdateAPIBase sets the "api_base" field to the value that was provided on create.
+func (u *XunjiServiceUpsertBulk) UpdateAPIBase() *XunjiServiceUpsertBulk {
+	return u.Update(func(s *XunjiServiceUpsert) {
+		s.UpdateAPIBase()
+	})
+}
+
+// ClearAPIBase clears the value of the "api_base" field.
+func (u *XunjiServiceUpsertBulk) ClearAPIBase() *XunjiServiceUpsertBulk {
+	return u.Update(func(s *XunjiServiceUpsert) {
+		s.ClearAPIBase()
+	})
+}
+
+// SetAPIKey sets the "api_key" field.
+func (u *XunjiServiceUpsertBulk) SetAPIKey(v string) *XunjiServiceUpsertBulk {
+	return u.Update(func(s *XunjiServiceUpsert) {
+		s.SetAPIKey(v)
+	})
+}
+
+// UpdateAPIKey sets the "api_key" field to the value that was provided on create.
+func (u *XunjiServiceUpsertBulk) UpdateAPIKey() *XunjiServiceUpsertBulk {
+	return u.Update(func(s *XunjiServiceUpsert) {
+		s.UpdateAPIKey()
+	})
+}
+
+// ClearAPIKey clears the value of the "api_key" field.
+func (u *XunjiServiceUpsertBulk) ClearAPIKey() *XunjiServiceUpsertBulk {
+	return u.Update(func(s *XunjiServiceUpsert) {
+		s.ClearAPIKey()
+	})
+}
+
+// Exec executes the query.
+func (u *XunjiServiceUpsertBulk) 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 XunjiServiceCreateBulk instead", i)
+		}
+	}
+	if len(u.create.conflict) == 0 {
+		return errors.New("ent: missing options for XunjiServiceCreateBulk.OnConflict")
+	}
+	return u.create.Exec(ctx)
+}
+
+// ExecX is like Exec, but panics if an error occurs.
+func (u *XunjiServiceUpsertBulk) ExecX(ctx context.Context) {
+	if err := u.create.Exec(ctx); err != nil {
+		panic(err)
+	}
+}

+ 88 - 0
ent/xunjiservice_delete.go

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

+ 605 - 0
ent/xunjiservice_query.go

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

+ 735 - 0
ent/xunjiservice_update.go

@@ -0,0 +1,735 @@
+// Code generated by ent, DO NOT EDIT.
+
+package ent
+
+import (
+	"context"
+	"errors"
+	"fmt"
+	"time"
+	"wechat-api/ent/agent"
+	"wechat-api/ent/predicate"
+	"wechat-api/ent/xunjiservice"
+
+	"entgo.io/ent/dialect/sql"
+	"entgo.io/ent/dialect/sql/sqlgraph"
+	"entgo.io/ent/schema/field"
+)
+
+// XunjiServiceUpdate is the builder for updating XunjiService entities.
+type XunjiServiceUpdate struct {
+	config
+	hooks    []Hook
+	mutation *XunjiServiceMutation
+}
+
+// Where appends a list predicates to the XunjiServiceUpdate builder.
+func (xsu *XunjiServiceUpdate) Where(ps ...predicate.XunjiService) *XunjiServiceUpdate {
+	xsu.mutation.Where(ps...)
+	return xsu
+}
+
+// SetUpdatedAt sets the "updated_at" field.
+func (xsu *XunjiServiceUpdate) SetUpdatedAt(t time.Time) *XunjiServiceUpdate {
+	xsu.mutation.SetUpdatedAt(t)
+	return xsu
+}
+
+// SetStatus sets the "status" field.
+func (xsu *XunjiServiceUpdate) SetStatus(u uint8) *XunjiServiceUpdate {
+	xsu.mutation.ResetStatus()
+	xsu.mutation.SetStatus(u)
+	return xsu
+}
+
+// SetNillableStatus sets the "status" field if the given value is not nil.
+func (xsu *XunjiServiceUpdate) SetNillableStatus(u *uint8) *XunjiServiceUpdate {
+	if u != nil {
+		xsu.SetStatus(*u)
+	}
+	return xsu
+}
+
+// AddStatus adds u to the "status" field.
+func (xsu *XunjiServiceUpdate) AddStatus(u int8) *XunjiServiceUpdate {
+	xsu.mutation.AddStatus(u)
+	return xsu
+}
+
+// ClearStatus clears the value of the "status" field.
+func (xsu *XunjiServiceUpdate) ClearStatus() *XunjiServiceUpdate {
+	xsu.mutation.ClearStatus()
+	return xsu
+}
+
+// SetDeletedAt sets the "deleted_at" field.
+func (xsu *XunjiServiceUpdate) SetDeletedAt(t time.Time) *XunjiServiceUpdate {
+	xsu.mutation.SetDeletedAt(t)
+	return xsu
+}
+
+// SetNillableDeletedAt sets the "deleted_at" field if the given value is not nil.
+func (xsu *XunjiServiceUpdate) SetNillableDeletedAt(t *time.Time) *XunjiServiceUpdate {
+	if t != nil {
+		xsu.SetDeletedAt(*t)
+	}
+	return xsu
+}
+
+// ClearDeletedAt clears the value of the "deleted_at" field.
+func (xsu *XunjiServiceUpdate) ClearDeletedAt() *XunjiServiceUpdate {
+	xsu.mutation.ClearDeletedAt()
+	return xsu
+}
+
+// SetXunjiID sets the "xunji_id" field.
+func (xsu *XunjiServiceUpdate) SetXunjiID(u uint64) *XunjiServiceUpdate {
+	xsu.mutation.ResetXunjiID()
+	xsu.mutation.SetXunjiID(u)
+	return xsu
+}
+
+// SetNillableXunjiID sets the "xunji_id" field if the given value is not nil.
+func (xsu *XunjiServiceUpdate) SetNillableXunjiID(u *uint64) *XunjiServiceUpdate {
+	if u != nil {
+		xsu.SetXunjiID(*u)
+	}
+	return xsu
+}
+
+// AddXunjiID adds u to the "xunji_id" field.
+func (xsu *XunjiServiceUpdate) AddXunjiID(u int64) *XunjiServiceUpdate {
+	xsu.mutation.AddXunjiID(u)
+	return xsu
+}
+
+// SetAgentID sets the "agent_id" field.
+func (xsu *XunjiServiceUpdate) SetAgentID(u uint64) *XunjiServiceUpdate {
+	xsu.mutation.SetAgentID(u)
+	return xsu
+}
+
+// SetNillableAgentID sets the "agent_id" field if the given value is not nil.
+func (xsu *XunjiServiceUpdate) SetNillableAgentID(u *uint64) *XunjiServiceUpdate {
+	if u != nil {
+		xsu.SetAgentID(*u)
+	}
+	return xsu
+}
+
+// SetOrganizationID sets the "organization_id" field.
+func (xsu *XunjiServiceUpdate) SetOrganizationID(u uint64) *XunjiServiceUpdate {
+	xsu.mutation.ResetOrganizationID()
+	xsu.mutation.SetOrganizationID(u)
+	return xsu
+}
+
+// SetNillableOrganizationID sets the "organization_id" field if the given value is not nil.
+func (xsu *XunjiServiceUpdate) SetNillableOrganizationID(u *uint64) *XunjiServiceUpdate {
+	if u != nil {
+		xsu.SetOrganizationID(*u)
+	}
+	return xsu
+}
+
+// AddOrganizationID adds u to the "organization_id" field.
+func (xsu *XunjiServiceUpdate) AddOrganizationID(u int64) *XunjiServiceUpdate {
+	xsu.mutation.AddOrganizationID(u)
+	return xsu
+}
+
+// SetWxid sets the "wxid" field.
+func (xsu *XunjiServiceUpdate) SetWxid(s string) *XunjiServiceUpdate {
+	xsu.mutation.SetWxid(s)
+	return xsu
+}
+
+// SetNillableWxid sets the "wxid" field if the given value is not nil.
+func (xsu *XunjiServiceUpdate) SetNillableWxid(s *string) *XunjiServiceUpdate {
+	if s != nil {
+		xsu.SetWxid(*s)
+	}
+	return xsu
+}
+
+// SetAPIBase sets the "api_base" field.
+func (xsu *XunjiServiceUpdate) SetAPIBase(s string) *XunjiServiceUpdate {
+	xsu.mutation.SetAPIBase(s)
+	return xsu
+}
+
+// SetNillableAPIBase sets the "api_base" field if the given value is not nil.
+func (xsu *XunjiServiceUpdate) SetNillableAPIBase(s *string) *XunjiServiceUpdate {
+	if s != nil {
+		xsu.SetAPIBase(*s)
+	}
+	return xsu
+}
+
+// ClearAPIBase clears the value of the "api_base" field.
+func (xsu *XunjiServiceUpdate) ClearAPIBase() *XunjiServiceUpdate {
+	xsu.mutation.ClearAPIBase()
+	return xsu
+}
+
+// SetAPIKey sets the "api_key" field.
+func (xsu *XunjiServiceUpdate) SetAPIKey(s string) *XunjiServiceUpdate {
+	xsu.mutation.SetAPIKey(s)
+	return xsu
+}
+
+// SetNillableAPIKey sets the "api_key" field if the given value is not nil.
+func (xsu *XunjiServiceUpdate) SetNillableAPIKey(s *string) *XunjiServiceUpdate {
+	if s != nil {
+		xsu.SetAPIKey(*s)
+	}
+	return xsu
+}
+
+// ClearAPIKey clears the value of the "api_key" field.
+func (xsu *XunjiServiceUpdate) ClearAPIKey() *XunjiServiceUpdate {
+	xsu.mutation.ClearAPIKey()
+	return xsu
+}
+
+// SetAgent sets the "agent" edge to the Agent entity.
+func (xsu *XunjiServiceUpdate) SetAgent(a *Agent) *XunjiServiceUpdate {
+	return xsu.SetAgentID(a.ID)
+}
+
+// Mutation returns the XunjiServiceMutation object of the builder.
+func (xsu *XunjiServiceUpdate) Mutation() *XunjiServiceMutation {
+	return xsu.mutation
+}
+
+// ClearAgent clears the "agent" edge to the Agent entity.
+func (xsu *XunjiServiceUpdate) ClearAgent() *XunjiServiceUpdate {
+	xsu.mutation.ClearAgent()
+	return xsu
+}
+
+// Save executes the query and returns the number of nodes affected by the update operation.
+func (xsu *XunjiServiceUpdate) Save(ctx context.Context) (int, error) {
+	if err := xsu.defaults(); err != nil {
+		return 0, err
+	}
+	return withHooks(ctx, xsu.sqlSave, xsu.mutation, xsu.hooks)
+}
+
+// SaveX is like Save, but panics if an error occurs.
+func (xsu *XunjiServiceUpdate) SaveX(ctx context.Context) int {
+	affected, err := xsu.Save(ctx)
+	if err != nil {
+		panic(err)
+	}
+	return affected
+}
+
+// Exec executes the query.
+func (xsu *XunjiServiceUpdate) Exec(ctx context.Context) error {
+	_, err := xsu.Save(ctx)
+	return err
+}
+
+// ExecX is like Exec, but panics if an error occurs.
+func (xsu *XunjiServiceUpdate) ExecX(ctx context.Context) {
+	if err := xsu.Exec(ctx); err != nil {
+		panic(err)
+	}
+}
+
+// defaults sets the default values of the builder before save.
+func (xsu *XunjiServiceUpdate) defaults() error {
+	if _, ok := xsu.mutation.UpdatedAt(); !ok {
+		if xunjiservice.UpdateDefaultUpdatedAt == nil {
+			return fmt.Errorf("ent: uninitialized xunjiservice.UpdateDefaultUpdatedAt (forgotten import ent/runtime?)")
+		}
+		v := xunjiservice.UpdateDefaultUpdatedAt()
+		xsu.mutation.SetUpdatedAt(v)
+	}
+	return nil
+}
+
+// check runs all checks and user-defined validators on the builder.
+func (xsu *XunjiServiceUpdate) check() error {
+	if v, ok := xsu.mutation.OrganizationID(); ok {
+		if err := xunjiservice.OrganizationIDValidator(v); err != nil {
+			return &ValidationError{Name: "organization_id", err: fmt.Errorf(`ent: validator failed for field "XunjiService.organization_id": %w`, err)}
+		}
+	}
+	if _, ok := xsu.mutation.AgentID(); xsu.mutation.AgentCleared() && !ok {
+		return errors.New(`ent: clearing a required unique edge "XunjiService.agent"`)
+	}
+	return nil
+}
+
+func (xsu *XunjiServiceUpdate) sqlSave(ctx context.Context) (n int, err error) {
+	if err := xsu.check(); err != nil {
+		return n, err
+	}
+	_spec := sqlgraph.NewUpdateSpec(xunjiservice.Table, xunjiservice.Columns, sqlgraph.NewFieldSpec(xunjiservice.FieldID, field.TypeUint64))
+	if ps := xsu.mutation.predicates; len(ps) > 0 {
+		_spec.Predicate = func(selector *sql.Selector) {
+			for i := range ps {
+				ps[i](selector)
+			}
+		}
+	}
+	if value, ok := xsu.mutation.UpdatedAt(); ok {
+		_spec.SetField(xunjiservice.FieldUpdatedAt, field.TypeTime, value)
+	}
+	if value, ok := xsu.mutation.Status(); ok {
+		_spec.SetField(xunjiservice.FieldStatus, field.TypeUint8, value)
+	}
+	if value, ok := xsu.mutation.AddedStatus(); ok {
+		_spec.AddField(xunjiservice.FieldStatus, field.TypeUint8, value)
+	}
+	if xsu.mutation.StatusCleared() {
+		_spec.ClearField(xunjiservice.FieldStatus, field.TypeUint8)
+	}
+	if value, ok := xsu.mutation.DeletedAt(); ok {
+		_spec.SetField(xunjiservice.FieldDeletedAt, field.TypeTime, value)
+	}
+	if xsu.mutation.DeletedAtCleared() {
+		_spec.ClearField(xunjiservice.FieldDeletedAt, field.TypeTime)
+	}
+	if value, ok := xsu.mutation.XunjiID(); ok {
+		_spec.SetField(xunjiservice.FieldXunjiID, field.TypeUint64, value)
+	}
+	if value, ok := xsu.mutation.AddedXunjiID(); ok {
+		_spec.AddField(xunjiservice.FieldXunjiID, field.TypeUint64, value)
+	}
+	if value, ok := xsu.mutation.OrganizationID(); ok {
+		_spec.SetField(xunjiservice.FieldOrganizationID, field.TypeUint64, value)
+	}
+	if value, ok := xsu.mutation.AddedOrganizationID(); ok {
+		_spec.AddField(xunjiservice.FieldOrganizationID, field.TypeUint64, value)
+	}
+	if value, ok := xsu.mutation.Wxid(); ok {
+		_spec.SetField(xunjiservice.FieldWxid, field.TypeString, value)
+	}
+	if value, ok := xsu.mutation.APIBase(); ok {
+		_spec.SetField(xunjiservice.FieldAPIBase, field.TypeString, value)
+	}
+	if xsu.mutation.APIBaseCleared() {
+		_spec.ClearField(xunjiservice.FieldAPIBase, field.TypeString)
+	}
+	if value, ok := xsu.mutation.APIKey(); ok {
+		_spec.SetField(xunjiservice.FieldAPIKey, field.TypeString, value)
+	}
+	if xsu.mutation.APIKeyCleared() {
+		_spec.ClearField(xunjiservice.FieldAPIKey, field.TypeString)
+	}
+	if xsu.mutation.AgentCleared() {
+		edge := &sqlgraph.EdgeSpec{
+			Rel:     sqlgraph.M2O,
+			Inverse: true,
+			Table:   xunjiservice.AgentTable,
+			Columns: []string{xunjiservice.AgentColumn},
+			Bidi:    false,
+			Target: &sqlgraph.EdgeTarget{
+				IDSpec: sqlgraph.NewFieldSpec(agent.FieldID, field.TypeUint64),
+			},
+		}
+		_spec.Edges.Clear = append(_spec.Edges.Clear, edge)
+	}
+	if nodes := xsu.mutation.AgentIDs(); len(nodes) > 0 {
+		edge := &sqlgraph.EdgeSpec{
+			Rel:     sqlgraph.M2O,
+			Inverse: true,
+			Table:   xunjiservice.AgentTable,
+			Columns: []string{xunjiservice.AgentColumn},
+			Bidi:    false,
+			Target: &sqlgraph.EdgeTarget{
+				IDSpec: sqlgraph.NewFieldSpec(agent.FieldID, field.TypeUint64),
+			},
+		}
+		for _, k := range nodes {
+			edge.Target.Nodes = append(edge.Target.Nodes, k)
+		}
+		_spec.Edges.Add = append(_spec.Edges.Add, edge)
+	}
+	if n, err = sqlgraph.UpdateNodes(ctx, xsu.driver, _spec); err != nil {
+		if _, ok := err.(*sqlgraph.NotFoundError); ok {
+			err = &NotFoundError{xunjiservice.Label}
+		} else if sqlgraph.IsConstraintError(err) {
+			err = &ConstraintError{msg: err.Error(), wrap: err}
+		}
+		return 0, err
+	}
+	xsu.mutation.done = true
+	return n, nil
+}
+
+// XunjiServiceUpdateOne is the builder for updating a single XunjiService entity.
+type XunjiServiceUpdateOne struct {
+	config
+	fields   []string
+	hooks    []Hook
+	mutation *XunjiServiceMutation
+}
+
+// SetUpdatedAt sets the "updated_at" field.
+func (xsuo *XunjiServiceUpdateOne) SetUpdatedAt(t time.Time) *XunjiServiceUpdateOne {
+	xsuo.mutation.SetUpdatedAt(t)
+	return xsuo
+}
+
+// SetStatus sets the "status" field.
+func (xsuo *XunjiServiceUpdateOne) SetStatus(u uint8) *XunjiServiceUpdateOne {
+	xsuo.mutation.ResetStatus()
+	xsuo.mutation.SetStatus(u)
+	return xsuo
+}
+
+// SetNillableStatus sets the "status" field if the given value is not nil.
+func (xsuo *XunjiServiceUpdateOne) SetNillableStatus(u *uint8) *XunjiServiceUpdateOne {
+	if u != nil {
+		xsuo.SetStatus(*u)
+	}
+	return xsuo
+}
+
+// AddStatus adds u to the "status" field.
+func (xsuo *XunjiServiceUpdateOne) AddStatus(u int8) *XunjiServiceUpdateOne {
+	xsuo.mutation.AddStatus(u)
+	return xsuo
+}
+
+// ClearStatus clears the value of the "status" field.
+func (xsuo *XunjiServiceUpdateOne) ClearStatus() *XunjiServiceUpdateOne {
+	xsuo.mutation.ClearStatus()
+	return xsuo
+}
+
+// SetDeletedAt sets the "deleted_at" field.
+func (xsuo *XunjiServiceUpdateOne) SetDeletedAt(t time.Time) *XunjiServiceUpdateOne {
+	xsuo.mutation.SetDeletedAt(t)
+	return xsuo
+}
+
+// SetNillableDeletedAt sets the "deleted_at" field if the given value is not nil.
+func (xsuo *XunjiServiceUpdateOne) SetNillableDeletedAt(t *time.Time) *XunjiServiceUpdateOne {
+	if t != nil {
+		xsuo.SetDeletedAt(*t)
+	}
+	return xsuo
+}
+
+// ClearDeletedAt clears the value of the "deleted_at" field.
+func (xsuo *XunjiServiceUpdateOne) ClearDeletedAt() *XunjiServiceUpdateOne {
+	xsuo.mutation.ClearDeletedAt()
+	return xsuo
+}
+
+// SetXunjiID sets the "xunji_id" field.
+func (xsuo *XunjiServiceUpdateOne) SetXunjiID(u uint64) *XunjiServiceUpdateOne {
+	xsuo.mutation.ResetXunjiID()
+	xsuo.mutation.SetXunjiID(u)
+	return xsuo
+}
+
+// SetNillableXunjiID sets the "xunji_id" field if the given value is not nil.
+func (xsuo *XunjiServiceUpdateOne) SetNillableXunjiID(u *uint64) *XunjiServiceUpdateOne {
+	if u != nil {
+		xsuo.SetXunjiID(*u)
+	}
+	return xsuo
+}
+
+// AddXunjiID adds u to the "xunji_id" field.
+func (xsuo *XunjiServiceUpdateOne) AddXunjiID(u int64) *XunjiServiceUpdateOne {
+	xsuo.mutation.AddXunjiID(u)
+	return xsuo
+}
+
+// SetAgentID sets the "agent_id" field.
+func (xsuo *XunjiServiceUpdateOne) SetAgentID(u uint64) *XunjiServiceUpdateOne {
+	xsuo.mutation.SetAgentID(u)
+	return xsuo
+}
+
+// SetNillableAgentID sets the "agent_id" field if the given value is not nil.
+func (xsuo *XunjiServiceUpdateOne) SetNillableAgentID(u *uint64) *XunjiServiceUpdateOne {
+	if u != nil {
+		xsuo.SetAgentID(*u)
+	}
+	return xsuo
+}
+
+// SetOrganizationID sets the "organization_id" field.
+func (xsuo *XunjiServiceUpdateOne) SetOrganizationID(u uint64) *XunjiServiceUpdateOne {
+	xsuo.mutation.ResetOrganizationID()
+	xsuo.mutation.SetOrganizationID(u)
+	return xsuo
+}
+
+// SetNillableOrganizationID sets the "organization_id" field if the given value is not nil.
+func (xsuo *XunjiServiceUpdateOne) SetNillableOrganizationID(u *uint64) *XunjiServiceUpdateOne {
+	if u != nil {
+		xsuo.SetOrganizationID(*u)
+	}
+	return xsuo
+}
+
+// AddOrganizationID adds u to the "organization_id" field.
+func (xsuo *XunjiServiceUpdateOne) AddOrganizationID(u int64) *XunjiServiceUpdateOne {
+	xsuo.mutation.AddOrganizationID(u)
+	return xsuo
+}
+
+// SetWxid sets the "wxid" field.
+func (xsuo *XunjiServiceUpdateOne) SetWxid(s string) *XunjiServiceUpdateOne {
+	xsuo.mutation.SetWxid(s)
+	return xsuo
+}
+
+// SetNillableWxid sets the "wxid" field if the given value is not nil.
+func (xsuo *XunjiServiceUpdateOne) SetNillableWxid(s *string) *XunjiServiceUpdateOne {
+	if s != nil {
+		xsuo.SetWxid(*s)
+	}
+	return xsuo
+}
+
+// SetAPIBase sets the "api_base" field.
+func (xsuo *XunjiServiceUpdateOne) SetAPIBase(s string) *XunjiServiceUpdateOne {
+	xsuo.mutation.SetAPIBase(s)
+	return xsuo
+}
+
+// SetNillableAPIBase sets the "api_base" field if the given value is not nil.
+func (xsuo *XunjiServiceUpdateOne) SetNillableAPIBase(s *string) *XunjiServiceUpdateOne {
+	if s != nil {
+		xsuo.SetAPIBase(*s)
+	}
+	return xsuo
+}
+
+// ClearAPIBase clears the value of the "api_base" field.
+func (xsuo *XunjiServiceUpdateOne) ClearAPIBase() *XunjiServiceUpdateOne {
+	xsuo.mutation.ClearAPIBase()
+	return xsuo
+}
+
+// SetAPIKey sets the "api_key" field.
+func (xsuo *XunjiServiceUpdateOne) SetAPIKey(s string) *XunjiServiceUpdateOne {
+	xsuo.mutation.SetAPIKey(s)
+	return xsuo
+}
+
+// SetNillableAPIKey sets the "api_key" field if the given value is not nil.
+func (xsuo *XunjiServiceUpdateOne) SetNillableAPIKey(s *string) *XunjiServiceUpdateOne {
+	if s != nil {
+		xsuo.SetAPIKey(*s)
+	}
+	return xsuo
+}
+
+// ClearAPIKey clears the value of the "api_key" field.
+func (xsuo *XunjiServiceUpdateOne) ClearAPIKey() *XunjiServiceUpdateOne {
+	xsuo.mutation.ClearAPIKey()
+	return xsuo
+}
+
+// SetAgent sets the "agent" edge to the Agent entity.
+func (xsuo *XunjiServiceUpdateOne) SetAgent(a *Agent) *XunjiServiceUpdateOne {
+	return xsuo.SetAgentID(a.ID)
+}
+
+// Mutation returns the XunjiServiceMutation object of the builder.
+func (xsuo *XunjiServiceUpdateOne) Mutation() *XunjiServiceMutation {
+	return xsuo.mutation
+}
+
+// ClearAgent clears the "agent" edge to the Agent entity.
+func (xsuo *XunjiServiceUpdateOne) ClearAgent() *XunjiServiceUpdateOne {
+	xsuo.mutation.ClearAgent()
+	return xsuo
+}
+
+// Where appends a list predicates to the XunjiServiceUpdate builder.
+func (xsuo *XunjiServiceUpdateOne) Where(ps ...predicate.XunjiService) *XunjiServiceUpdateOne {
+	xsuo.mutation.Where(ps...)
+	return xsuo
+}
+
+// Select allows selecting one or more fields (columns) of the returned entity.
+// The default is selecting all fields defined in the entity schema.
+func (xsuo *XunjiServiceUpdateOne) Select(field string, fields ...string) *XunjiServiceUpdateOne {
+	xsuo.fields = append([]string{field}, fields...)
+	return xsuo
+}
+
+// Save executes the query and returns the updated XunjiService entity.
+func (xsuo *XunjiServiceUpdateOne) Save(ctx context.Context) (*XunjiService, error) {
+	if err := xsuo.defaults(); err != nil {
+		return nil, err
+	}
+	return withHooks(ctx, xsuo.sqlSave, xsuo.mutation, xsuo.hooks)
+}
+
+// SaveX is like Save, but panics if an error occurs.
+func (xsuo *XunjiServiceUpdateOne) SaveX(ctx context.Context) *XunjiService {
+	node, err := xsuo.Save(ctx)
+	if err != nil {
+		panic(err)
+	}
+	return node
+}
+
+// Exec executes the query on the entity.
+func (xsuo *XunjiServiceUpdateOne) Exec(ctx context.Context) error {
+	_, err := xsuo.Save(ctx)
+	return err
+}
+
+// ExecX is like Exec, but panics if an error occurs.
+func (xsuo *XunjiServiceUpdateOne) ExecX(ctx context.Context) {
+	if err := xsuo.Exec(ctx); err != nil {
+		panic(err)
+	}
+}
+
+// defaults sets the default values of the builder before save.
+func (xsuo *XunjiServiceUpdateOne) defaults() error {
+	if _, ok := xsuo.mutation.UpdatedAt(); !ok {
+		if xunjiservice.UpdateDefaultUpdatedAt == nil {
+			return fmt.Errorf("ent: uninitialized xunjiservice.UpdateDefaultUpdatedAt (forgotten import ent/runtime?)")
+		}
+		v := xunjiservice.UpdateDefaultUpdatedAt()
+		xsuo.mutation.SetUpdatedAt(v)
+	}
+	return nil
+}
+
+// check runs all checks and user-defined validators on the builder.
+func (xsuo *XunjiServiceUpdateOne) check() error {
+	if v, ok := xsuo.mutation.OrganizationID(); ok {
+		if err := xunjiservice.OrganizationIDValidator(v); err != nil {
+			return &ValidationError{Name: "organization_id", err: fmt.Errorf(`ent: validator failed for field "XunjiService.organization_id": %w`, err)}
+		}
+	}
+	if _, ok := xsuo.mutation.AgentID(); xsuo.mutation.AgentCleared() && !ok {
+		return errors.New(`ent: clearing a required unique edge "XunjiService.agent"`)
+	}
+	return nil
+}
+
+func (xsuo *XunjiServiceUpdateOne) sqlSave(ctx context.Context) (_node *XunjiService, err error) {
+	if err := xsuo.check(); err != nil {
+		return _node, err
+	}
+	_spec := sqlgraph.NewUpdateSpec(xunjiservice.Table, xunjiservice.Columns, sqlgraph.NewFieldSpec(xunjiservice.FieldID, field.TypeUint64))
+	id, ok := xsuo.mutation.ID()
+	if !ok {
+		return nil, &ValidationError{Name: "id", err: errors.New(`ent: missing "XunjiService.id" for update`)}
+	}
+	_spec.Node.ID.Value = id
+	if fields := xsuo.fields; len(fields) > 0 {
+		_spec.Node.Columns = make([]string, 0, len(fields))
+		_spec.Node.Columns = append(_spec.Node.Columns, xunjiservice.FieldID)
+		for _, f := range fields {
+			if !xunjiservice.ValidColumn(f) {
+				return nil, &ValidationError{Name: f, err: fmt.Errorf("ent: invalid field %q for query", f)}
+			}
+			if f != xunjiservice.FieldID {
+				_spec.Node.Columns = append(_spec.Node.Columns, f)
+			}
+		}
+	}
+	if ps := xsuo.mutation.predicates; len(ps) > 0 {
+		_spec.Predicate = func(selector *sql.Selector) {
+			for i := range ps {
+				ps[i](selector)
+			}
+		}
+	}
+	if value, ok := xsuo.mutation.UpdatedAt(); ok {
+		_spec.SetField(xunjiservice.FieldUpdatedAt, field.TypeTime, value)
+	}
+	if value, ok := xsuo.mutation.Status(); ok {
+		_spec.SetField(xunjiservice.FieldStatus, field.TypeUint8, value)
+	}
+	if value, ok := xsuo.mutation.AddedStatus(); ok {
+		_spec.AddField(xunjiservice.FieldStatus, field.TypeUint8, value)
+	}
+	if xsuo.mutation.StatusCleared() {
+		_spec.ClearField(xunjiservice.FieldStatus, field.TypeUint8)
+	}
+	if value, ok := xsuo.mutation.DeletedAt(); ok {
+		_spec.SetField(xunjiservice.FieldDeletedAt, field.TypeTime, value)
+	}
+	if xsuo.mutation.DeletedAtCleared() {
+		_spec.ClearField(xunjiservice.FieldDeletedAt, field.TypeTime)
+	}
+	if value, ok := xsuo.mutation.XunjiID(); ok {
+		_spec.SetField(xunjiservice.FieldXunjiID, field.TypeUint64, value)
+	}
+	if value, ok := xsuo.mutation.AddedXunjiID(); ok {
+		_spec.AddField(xunjiservice.FieldXunjiID, field.TypeUint64, value)
+	}
+	if value, ok := xsuo.mutation.OrganizationID(); ok {
+		_spec.SetField(xunjiservice.FieldOrganizationID, field.TypeUint64, value)
+	}
+	if value, ok := xsuo.mutation.AddedOrganizationID(); ok {
+		_spec.AddField(xunjiservice.FieldOrganizationID, field.TypeUint64, value)
+	}
+	if value, ok := xsuo.mutation.Wxid(); ok {
+		_spec.SetField(xunjiservice.FieldWxid, field.TypeString, value)
+	}
+	if value, ok := xsuo.mutation.APIBase(); ok {
+		_spec.SetField(xunjiservice.FieldAPIBase, field.TypeString, value)
+	}
+	if xsuo.mutation.APIBaseCleared() {
+		_spec.ClearField(xunjiservice.FieldAPIBase, field.TypeString)
+	}
+	if value, ok := xsuo.mutation.APIKey(); ok {
+		_spec.SetField(xunjiservice.FieldAPIKey, field.TypeString, value)
+	}
+	if xsuo.mutation.APIKeyCleared() {
+		_spec.ClearField(xunjiservice.FieldAPIKey, field.TypeString)
+	}
+	if xsuo.mutation.AgentCleared() {
+		edge := &sqlgraph.EdgeSpec{
+			Rel:     sqlgraph.M2O,
+			Inverse: true,
+			Table:   xunjiservice.AgentTable,
+			Columns: []string{xunjiservice.AgentColumn},
+			Bidi:    false,
+			Target: &sqlgraph.EdgeTarget{
+				IDSpec: sqlgraph.NewFieldSpec(agent.FieldID, field.TypeUint64),
+			},
+		}
+		_spec.Edges.Clear = append(_spec.Edges.Clear, edge)
+	}
+	if nodes := xsuo.mutation.AgentIDs(); len(nodes) > 0 {
+		edge := &sqlgraph.EdgeSpec{
+			Rel:     sqlgraph.M2O,
+			Inverse: true,
+			Table:   xunjiservice.AgentTable,
+			Columns: []string{xunjiservice.AgentColumn},
+			Bidi:    false,
+			Target: &sqlgraph.EdgeTarget{
+				IDSpec: sqlgraph.NewFieldSpec(agent.FieldID, field.TypeUint64),
+			},
+		}
+		for _, k := range nodes {
+			edge.Target.Nodes = append(edge.Target.Nodes, k)
+		}
+		_spec.Edges.Add = append(_spec.Edges.Add, edge)
+	}
+	_node = &XunjiService{config: xsuo.config}
+	_spec.Assign = _node.assignValues
+	_spec.ScanValues = _node.scanValues
+	if err = sqlgraph.UpdateNode(ctx, xsuo.driver, _spec); err != nil {
+		if _, ok := err.(*sqlgraph.NotFoundError); ok {
+			err = &NotFoundError{xunjiservice.Label}
+		} else if sqlgraph.IsConstraintError(err) {
+			err = &ConstraintError{msg: err.Error(), wrap: err}
+		}
+		return nil, err
+	}
+	xsuo.mutation.done = true
+	return _node, nil
+}

+ 0 - 101
etc/wechat.yaml

@@ -1,101 +0,0 @@
-Name: Wechat.api
-Host: 0.0.0.0
-Port: 19101
-Timeout: 30000
-
-Mode: "dev"
-
-Auth:
-  AccessSecret: LnQD46hBde0AgFXBer8ZZZe3FgC
-  AccessExpire: 259200
-
-CROSConf:
-  Address: '*'
-
-Log:
-  ServiceName: WechatApiLogger
-  Mode: console
-  Encoding: plain
-  Stat: false
-  Path: /tmp
-  Level: info
-  Compress: false
-  KeepDays: 7
-  StackCoolDownMillis: 100
-
-DatabaseConf:
-  Type: mysql
-  Host: mysql-server
-  Port: 3306
-  DBName: wechat
-  Username: root
-  Password: simple-admin.
-  MaxOpenConn: 100
-  SSLMode: disable
-  CacheTime: 5
-
-CoreRpc:
-  # Target: k8s://default/core-rpc-svc:9101
-  Endpoints:
-    - core-rpc:9101
-  Enabled: true
-
-RedisConf:
-  Host: redis-server:6379
-
-CasbinDatabaseConf:
-  Type: mysql
-  Host: mysql-server
-  Port: 3306
-  DBName: wechat_admin
-  Username: root
-  Password: simple-admin.
-  MaxOpenConn: 100
-  SSLMode: disable
-  CacheTime: 5
-
-CasbinConf:
-  ModelText: |
-    [request_definition]
-    r = sub, obj, act
-    [policy_definition]
-    p = sub, obj, act
-    [role_definition]
-    g = _, _
-    [policy_effect]
-    e = some(where (p.eft == allow))
-    [matchers]
-    m = r.sub == p.sub && keyMatch2(r.obj,p.obj) && r.act == p.act
-
-Miniprogram:
-  Appid: wx1452f34bba8fe718
-  Secret: 171fdab212fdde0d51b59fa59c9ee070
-  Redisaddr: redis-server:6379
-
-Aliyun:
-  ACCESS_KEY_ID: LTAI5tSJwCQyuaxXR3UxfnWw
-  ACCESS_KEY_SECRET: 0pv4xhSPJv9IPSxrkB52FspJk27W7V
-  OSS_ENDPOINT: sts.cn-beijing.aliyuncs.com
-  OSS_ROLEARN: acs:ram::1317798064750399:role/ramoss
-
-Fastgpt:
-  BASE_URL: https://newapi.gkscrm.com/v1
-  API_KEY: sk-ZQRNypQOC8ID5WbpCdF263C58dF44271842e86D408Bb3848
-
-Xiaoice:
-  SubscriptionKey: ccaa5a6ff70f4393a934e69b9ace31bb
-  GptbotsAuthorization: app-hQL7oVq57McK5VBHlsMfhtUD
-
-OpenAI:
-  BaseUrl: https://api.openai.com/v1
-  ApiKey: sk-ZQRNypQOC8ID5WbpCdF263C58dF44271842e86D408Bb3848
-
-FastgptMongoConf:
-  Url: mongodb://myusername:mypassword@47.251.25.21:27017/?connect=direct
-  DBName: fastgpt
-
-WebSocket:
-  -
-    Type: wecom
-    Name: default
-    Url: ws://wecom.gkscrm.com:15088  

+ 2 - 10
go.mod

@@ -43,15 +43,9 @@ require (
 	gorm.io/plugin/dbresolver v1.5.0
 )
 
-require (
-	github.com/invopop/jsonschema v0.13.0
-//github.com/openai/openai-go v0.1.0-alpha.62
-)
+require github.com/invopop/jsonschema v0.13.0
 
-require (
-	github.com/google/uuid v1.6.0
-	github.com/stretchr/testify v1.9.0
-)
+require github.com/google/uuid v1.6.0
 
 require (
 	ariga.io/atlas v0.19.2 // indirect
@@ -139,7 +133,6 @@ require (
 	github.com/patrickmn/go-cache v2.1.0+incompatible // indirect
 	github.com/pelletier/go-toml/v2 v2.1.1 // indirect
 	github.com/pkg/errors v0.9.1 // indirect
-	github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
 	github.com/prometheus/client_golang v1.19.0 // indirect
 	github.com/prometheus/client_model v0.5.0 // indirect
 	github.com/prometheus/common v0.48.0 // indirect
@@ -148,7 +141,6 @@ require (
 	github.com/quic-go/quic-go v0.42.0 // indirect
 	github.com/refraction-networking/utls v1.6.3 // indirect
 	github.com/spaolacci/murmur3 v1.1.0 // indirect
-	github.com/stretchr/objx v0.5.2 // indirect
 	github.com/tidwall/gjson v1.17.1 // indirect
 	github.com/tidwall/match v1.1.1 // indirect
 	github.com/tidwall/pretty v1.2.1 // indirect

+ 0 - 2
go.sum

@@ -635,8 +635,6 @@ github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+
 github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE=
 github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
 github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
-github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY=
-github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA=
 github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
 github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
 github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=

+ 113 - 0
hook/credit/credit.go

@@ -0,0 +1,113 @@
+package credit
+
+import (
+	"context"
+	"fmt"
+	"wechat-api/ent"
+	"wechat-api/ent/creditbalance"
+	"wechat-api/ent/custom_types"
+	"wechat-api/ent/usagetotal"
+	"wechat-api/hook/dify"
+)
+
+func AddCreditUsage(tx *ent.Tx, ctx context.Context,
+	agentId string, userId string, departmentId uint64,
+	question *string, answer *string,
+	originalData *custom_types.OriginalData, chatData *dify.ChatResp) error {
+	// 积分明细表记录使用量
+	modelName, price := GetModelPrice()
+	number := ComputePrice(price, chatData.Metadata.Usage.TotalTokens)
+
+	// 记录Token使用信息
+	usageDetailItem, err := tx.UsageDetail.Create().
+		SetType(3).            //1-微信 2-名片 3-智能体
+		SetBotID(agentId).     //智能体ID
+		SetReceiverID(userId). //接收者userID
+		SetApp(8).             //8-智能体
+		SetSessionID(0).
+		SetRequest(*question).
+		SetResponse(*answer).
+		SetOriginalData(*originalData).
+		SetTotalTokens(chatData.Metadata.Usage.TotalTokens).
+		SetPromptTokens(chatData.Metadata.Usage.PromptTokens).
+		SetCompletionTokens(chatData.Metadata.Usage.CompletionTokens).
+		SetModel(modelName).
+		SetCredits(number).
+		Save(ctx)
+
+	if err != nil {
+		fmt.Printf("create usage_detail failed:%v\n", err)
+		return err
+	}
+
+	// 记录Token使用总量
+	usageTotal, err := tx.UsageTotal.Query().Where(usagetotal.OrganizationID(departmentId)).First(ctx)
+	if err != nil {
+		if ent.IsNotFound(err) {
+			usageTotal, err = tx.UsageTotal.Create().
+				SetBotID(agentId).
+				SetTotalTokens(chatData.Metadata.Usage.TotalTokens).
+				SetEndIndex(usageDetailItem.ID).
+				SetOrganizationID(departmentId).
+				Save(ctx)
+		} else {
+			fmt.Printf("create usage_total failed:organization_id:%v err:%v\n", departmentId, err)
+			return err
+		}
+	} else {
+		// 更新Token使用总量
+		_, err = tx.UsageTotal.Update().
+			Where(usagetotal.OrganizationID(departmentId)).
+			SetTotalTokens(usageTotal.TotalTokens + chatData.Metadata.Usage.TotalTokens).
+			SetEndIndex(usageDetailItem.ID).
+			Save(ctx)
+		if err != nil {
+			fmt.Printf("update usage_total failed:organization_id:%v err:%v\n", departmentId, err)
+			return err
+		}
+	}
+
+	creditBalanceItem, err := tx.CreditBalance.Query().Where(creditbalance.OrganizationID(departmentId)).First(ctx)
+	if err != nil {
+		if ent.IsNotFound(err) {
+			creditBalanceItem, err = tx.CreditBalance.Create().
+				SetOrganizationID(departmentId).
+				SetBalance(0).
+				Save(ctx)
+			if err != nil {
+				fmt.Printf("create credit_balance failed. organization_id:%v error:%v\n", departmentId, err)
+				return err
+			}
+		} else {
+			fmt.Printf("query credit_balance failed: organization_id:%v error:%v\n", departmentId, err)
+			return err
+		}
+	}
+
+	// 积分使用明细记录
+	beforeNumber := creditBalanceItem.Balance
+	afterNumber := Subtraction(beforeNumber, number)
+	_, err = tx.CreditUsage.Create().
+		SetUserID(userId).
+		SetNumber(number).
+		SetBeforeNumber(beforeNumber).
+		SetAfterNumber(afterNumber).
+		SetNtype(1).
+		SetNid(usageDetailItem.ID).
+		SetTable("usage_detail").
+		SetOrganizationID(departmentId).
+		Save(ctx)
+	if err != nil {
+		fmt.Printf("create credit_usage failed:%v\n", err)
+		return err
+	}
+
+	// 积分账户扣减积分
+	_, err = tx.CreditBalance.Update().Where(creditbalance.OrganizationID(departmentId)).SetBalance(afterNumber).Save(ctx)
+	if err != nil {
+		fmt.Printf("update credit_balance failed: organization_id:%v error:%v\n", departmentId, err)
+		return err
+	}
+
+	return nil
+}

+ 79 - 0
hook/credit/models.go

@@ -0,0 +1,79 @@
+package credit
+
+import "math"
+
+var modelArray = []string{
+	"o1",
+	"gpt-4o",
+	"gpt-4.1",
+	"o3-mini",
+	"moonshot-v1-32k",
+	"deepseek-r1",
+	"moonshot-v1-8k",
+	"gpt-4.1-mini",
+	"gpt-3.5-turbo",
+	"qwen-max",
+	"doubao1.5-pro-256k",
+	"deepseek-v3",
+	"qwq-32b-preview",
+	"gpt-4o-mini",
+	"qwen2.5-14b-instruct-1m",
+	"gpt-4.1-nano",
+	"doubao1.5-pro",
+	"doubao1.5-pro-32k",
+	"chatglm3",
+	"qwen-turbo",
+	"doubao1.5-lite-32k",
+}
+
+var priceArray = []float64{
+	0.0001,
+	0.00001667,
+	0.00001333,
+	0.00000733,
+	0.00000548,
+	0.00000365,
+	0.00000274,
+	0.00000267,
+	0.0000025,
+	0.00000219,
+	0.00000205,
+	0.00000183,
+	0.00000137,
+	0.000001,
+	0.00000068,
+	0.00000067,
+	0.00000046,
+	0.00000046,
+	0.00000023,
+	0.00000014,
+	0.00000014,
+}
+
+func getModelName() string {
+	return "gpt-4o"
+}
+
+func GetModelPrice() (model string, price float64) {
+	difyModelName := getModelName()
+	for i, v := range modelArray {
+		if v == difyModelName {
+			return v, priceArray[i]
+		}
+	}
+
+	return modelArray[0], priceArray[0]
+}
+
+func ComputePrice(price float64, tokens uint64) float64 {
+	scale := float64(1000000)
+	return math.Round(price*float64(tokens)*scale) / scale
+}
+
+// Subtraction() 保留小数点后6位的精确减法
+func Subtraction(number1, number2 float64) float64 {
+	d1 := number1 * 1000000
+	d2 := number2 * 1000000
+	res := math.Floor(d1-d2) / 1000000
+	return res
+}

+ 3 - 1
hook/message.go

@@ -27,7 +27,7 @@ func (h *Hook) ConfigureMsgRecive(isEnable string, url string) (err error) {
 }
 
 // SendTextMsg 发送微信文本消息
-func (h *Hook) SendTextMsg(wxid, msg, wxWxid string) error {
+func (h *Hook) SendTextMsg(wxid, msg, wxWxid string, msgId int64) error {
 	if h.ServerIp == "" || h.ServerIp == "0" {
 		conn, err := h.connWorkPhone()
 		if err != nil {
@@ -73,6 +73,7 @@ func (h *Hook) SendTextMsg(wxid, msg, wxWxid string) error {
 					"ConvId":      wxid,
 					"ContentType": "Text",
 					"Content":     encodedString,
+					"TaskId":      msgId,
 				},
 			}
 		} else {
@@ -83,6 +84,7 @@ func (h *Hook) SendTextMsg(wxid, msg, wxWxid string) error {
 					"FriendId":    wxid,
 					"ContentType": "Text",
 					"Content":     encodedString,
+					"MsgId":       msgId,
 				},
 			}
 		}

+ 0 - 1
internal/handler/auth/login_handler.go

@@ -4,7 +4,6 @@ import (
 	"net/http"
 
 	"github.com/zeromicro/go-zero/rest/httpx"
-
 	"wechat-api/internal/logic/auth"
 	"wechat-api/internal/svc"
 	"wechat-api/internal/types"

+ 31 - 0
internal/handler/auth/logout_handler.go

@@ -0,0 +1,31 @@
+package auth
+
+import (
+	"net/http"
+
+	"github.com/zeromicro/go-zero/rest/httpx"
+
+	"wechat-api/internal/logic/auth"
+	"wechat-api/internal/svc"
+)
+
+// swagger:route get /auth/logout auth Logout
+//
+// Log out | 退出登陆
+//
+// Log out | 退出登陆
+//
+// Responses:
+//  200: BaseMsgResp
+
+func LogoutHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
+	return func(w http.ResponseWriter, r *http.Request) {
+		l := auth.NewLogoutLogic(r.Context(), svcCtx)
+		resp, err := l.Logout()
+		if err != nil {
+			httpx.ErrorCtx(r.Context(), w, err)
+		} else {
+			httpx.OkJsonCtx(r.Context(), w, resp)
+		}
+	}
+}

+ 44 - 0
internal/handler/chat/send_text_msg_handler.go

@@ -0,0 +1,44 @@
+package chat
+
+import (
+	"net/http"
+
+	"github.com/zeromicro/go-zero/rest/httpx"
+
+	"wechat-api/internal/logic/chat"
+	"wechat-api/internal/svc"
+	"wechat-api/internal/types"
+)
+
+// swagger:route post /v1/wx/sendTextMsg chat SendTextMsg
+//
+
+//
+
+//
+// Parameters:
+//  + name: body
+//    require: true
+//    in: body
+//    type: SendTextMsgReq
+//
+// Responses:
+//  200: BaseMsgResp
+
+func SendTextMsgHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
+	return func(w http.ResponseWriter, r *http.Request) {
+		var req types.SendTextMsgReq
+		if err := httpx.Parse(r, &req, true); err != nil {
+			httpx.ErrorCtx(r.Context(), w, err)
+			return
+		}
+
+		l := chat.NewSendTextMsgLogic(r.Context(), svcCtx)
+		resp, err := l.SendTextMsg(&req)
+		if err != nil {
+			httpx.ErrorCtx(r.Context(), w, err)
+		} else {
+			httpx.OkJsonCtx(r.Context(), w, resp)
+		}
+	}
+}

+ 105 - 1
internal/handler/routes.go

@@ -1,5 +1,5 @@
 // Code generated by goctl. DO NOT EDIT.
-// goctls v1.10.4
+// goctls v1.10.1
 
 package handler
 
@@ -52,10 +52,13 @@ import (
 	whatsapp "wechat-api/internal/handler/whatsapp"
 	whatsapp_channel "wechat-api/internal/handler/whatsapp_channel"
 	work_experience "wechat-api/internal/handler/work_experience"
+	wp_wecom "wechat-api/internal/handler/wp_wecom"
 	wxcard "wechat-api/internal/handler/wxcard"
 	wxcarduser "wechat-api/internal/handler/wxcarduser"
 	wxcardvisit "wechat-api/internal/handler/wxcardvisit"
 	xiaoice "wechat-api/internal/handler/xiaoice"
+	xunji "wechat-api/internal/handler/xunji"
+	xunji_service "wechat-api/internal/handler/xunji_service"
 	"wechat-api/internal/svc"
 
 	"github.com/zeromicro/go-zero/rest"
@@ -918,6 +921,19 @@ func RegisterHandlers(server *rest.Server, serverCtx *svc.ServiceContext) {
 
 	server.AddRoutes(
 		rest.WithMiddlewares(
+			[]rest.Middleware{serverCtx.OpenAuthority},
+			[]rest.Route{
+				{
+					Method:  http.MethodPost,
+					Path:    "/wx/sendTextMsg",
+					Handler: chat.SendTextMsgHandler(serverCtx),
+				},
+			}...,
+		),
+	)
+
+	server.AddRoutes(
+		rest.WithMiddlewares(
 			[]rest.Middleware{serverCtx.Authority},
 			[]rest.Route{
 				{
@@ -2106,6 +2122,94 @@ func RegisterHandlers(server *rest.Server, serverCtx *svc.ServiceContext) {
 	)
 
 	server.AddRoutes(
+		rest.WithMiddlewares(
+			[]rest.Middleware{serverCtx.Authority},
+			[]rest.Route{
+				{
+					Method:  http.MethodPost,
+					Path:    "/xunji/create",
+					Handler: xunji.CreateXunjiHandler(serverCtx),
+				},
+				{
+					Method:  http.MethodPost,
+					Path:    "/xunji/update",
+					Handler: xunji.UpdateXunjiHandler(serverCtx),
+				},
+				{
+					Method:  http.MethodPost,
+					Path:    "/xunji/delete",
+					Handler: xunji.DeleteXunjiHandler(serverCtx),
+				},
+				{
+					Method:  http.MethodPost,
+					Path:    "/xunji/list",
+					Handler: xunji.GetXunjiListHandler(serverCtx),
+				},
+				{
+					Method:  http.MethodPost,
+					Path:    "/xunji",
+					Handler: xunji.GetXunjiByIdHandler(serverCtx),
+				},
+				{
+					Method:  http.MethodPost,
+					Path:    "/xunji/detail",
+					Handler: xunji.GetXunjiHandler(serverCtx),
+				},
+			}...,
+		),
+		rest.WithJwt(serverCtx.Config.Auth.AccessSecret),
+	)
+
+	server.AddRoutes(
+		rest.WithMiddlewares(
+			[]rest.Middleware{serverCtx.Authority},
+			[]rest.Route{
+				{
+					Method:  http.MethodPost,
+					Path:    "/xunji_service/create",
+					Handler: xunji_service.CreateXunjiServiceHandler(serverCtx),
+				},
+				{
+					Method:  http.MethodPost,
+					Path:    "/xunji_service/update",
+					Handler: xunji_service.UpdateXunjiServiceHandler(serverCtx),
+				},
+				{
+					Method:  http.MethodPost,
+					Path:    "/xunji_service/delete",
+					Handler: xunji_service.DeleteXunjiServiceHandler(serverCtx),
+				},
+				{
+					Method:  http.MethodPost,
+					Path:    "/xunji_service/list",
+					Handler: xunji_service.GetXunjiServiceListHandler(serverCtx),
+				},
+				{
+					Method:  http.MethodPost,
+					Path:    "/xunji_service",
+					Handler: xunji_service.GetXunjiServiceByIdHandler(serverCtx),
+				},
+			}...,
+		),
+		rest.WithJwt(serverCtx.Config.Auth.AccessSecret),
+	)
+
+	server.AddRoutes(
+		[]rest.Route{
+			{
+				Method:  http.MethodPost,
+				Path:    "/wp/wecom/send_msg",
+				Handler: wp_wecom.SendMsgHandler(serverCtx),
+			},
+			{
+				Method:  http.MethodPost,
+				Path:    "/wp/wecom/send_msg_by_chan",
+				Handler: wp_wecom.SendMsgByChanHandler(serverCtx),
+			},
+		},
+	)
+
+	server.AddRoutes(
 		[]rest.Route{
 			{
 				Method:  http.MethodGet,

+ 44 - 0
internal/handler/wp_wecom/send_msg_by_chan_handler.go

@@ -0,0 +1,44 @@
+package wp_wecom
+
+import (
+	"net/http"
+
+	"github.com/zeromicro/go-zero/rest/httpx"
+
+	"wechat-api/internal/logic/wp_wecom"
+	"wechat-api/internal/svc"
+	"wechat-api/internal/types"
+)
+
+// swagger:route post /wp/wecom/send_msg_by_chan wp_wecom SendMsgByChan
+//
+
+//
+
+//
+// Parameters:
+//  + name: body
+//    require: true
+//    in: body
+//    type: WpWecomMsgReq
+//
+// Responses:
+//  200: BaseMsgResp
+
+func SendMsgByChanHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
+	return func(w http.ResponseWriter, r *http.Request) {
+		var req types.WpWecomMsgReq
+		if err := httpx.Parse(r, &req, true); err != nil {
+			httpx.ErrorCtx(r.Context(), w, err)
+			return
+		}
+
+		l := wp_wecom.NewSendMsgByChanLogic(r.Context(), svcCtx)
+		resp, err := l.SendMsgByChan(&req)
+		if err != nil {
+			httpx.ErrorCtx(r.Context(), w, err)
+		} else {
+			httpx.OkJsonCtx(r.Context(), w, resp)
+		}
+	}
+}

+ 44 - 0
internal/handler/wp_wecom/send_msg_handler.go

@@ -0,0 +1,44 @@
+package wp_wecom
+
+import (
+	"net/http"
+
+	"github.com/zeromicro/go-zero/rest/httpx"
+
+	"wechat-api/internal/logic/wp_wecom"
+	"wechat-api/internal/svc"
+	"wechat-api/internal/types"
+)
+
+// swagger:route get /wp/wecom/send_msg wp_wecom SendMsg
+//
+
+//
+
+//
+// Parameters:
+//  + name: body
+//    require: true
+//    in: body
+//    type: WpWecomMsgReq
+//
+// Responses:
+//  200: BaseMsgResp
+
+func SendMsgHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
+	return func(w http.ResponseWriter, r *http.Request) {
+		var req types.WpWecomMsgReq
+		if err := httpx.Parse(r, &req, true); err != nil {
+			httpx.ErrorCtx(r.Context(), w, err)
+			return
+		}
+
+		l := wp_wecom.NewSendMsgLogic(r.Context(), svcCtx)
+		resp, err := l.SendMsg(&req)
+		if err != nil {
+			httpx.ErrorCtx(r.Context(), w, err)
+		} else {
+			httpx.OkJsonCtx(r.Context(), w, resp)
+		}
+	}
+}

+ 44 - 0
internal/handler/xunji/create_xunji_handler.go

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

Alguns arquivos não foram mostrados porque muitos arquivos mudaram nesse diff