package crontask import ( "fmt" "github.com/zeromicro/go-zero/core/logx" "strconv" "time" "wechat-api/ent" "wechat-api/ent/creditbalance" "wechat-api/ent/creditusage" "wechat-api/ent/usagedetail" ) func (l *CronTask) computeHistoricalCredit() { // 获取所有机器人信息 //wxbots, err := l.svcCtx.DB.Wx.Query().Select(wx.FieldWxid, wx.FieldID, wx.FieldOrganizationID).All(l.ctx) //if err != nil { // l.Errorf("fetch wxids error:%v\n", err) // return //} // //wxbotsSet := make(map[uint64][]*ent.Wx) //for _, bot := range wxbots { // if !strings.HasPrefix(bot.Wxid, "temp-") { // wxbotsSet[bot.OrganizationID] = append(wxbotsSet[bot.OrganizationID], bot) // } //} orgBots := []OrgBot{} err := l.svcCtx.DB.UsageDetail.Query(). GroupBy(usagedetail.FieldOrganizationID, usagedetail.FieldBotID). Aggregate(). Scan(l.ctx, &orgBots) if err != nil { l.Errorf("group usage_detail error: %v", err) return } wxbotsSet := make(map[uint64][]string) for _, ob := range orgBots { wxbotsSet[ob.OrganizationID] = append(wxbotsSet[ob.OrganizationID], ob.BotID) } logx.Info("wxbotsSet: ", wxbotsSet) /* 计算本小时的数据 1. 查询出上小时里所有 usagedetail 内容 2. 挨个遍历他的 bot_id ,再查询他的 bot_id 相关的参数 3. 遍历的时候可能有重复,所以要先检查是否生成了数据,如果有就忽略,没有再生成 ---------------------------------------------------------------------------------------------------------- */ // 获取当前时间 //now := time.Now() //start := time.Date(2024, 12, 25, 0, 0, 0, 0, time.Local) start := time.Date(2025, 4, 1, 0, 0, 0, 0, time.Local) end := time.Date(2025, 4, 24, 23, 0, 0, 0, time.Local) //start := time.Date(2025, 3, 18, 0, 0, 0, 0, time.Local) //end := time.Date(2025, 3, 19, 23, 0, 0, 0, time.Local) balanceSet := make(map[uint64]float64) for now := end; !now.Before(start); now = now.Add(-time.Hour) { fmt.Println(now.Format("2006-01-02 15:00:00")) // 获取本小时的第一分钟 currentHour := time.Date(now.Year(), now.Month(), now.Day(), now.Hour(), 0, 0, 0, now.Location()) //currentHourInt, _ := strconv.Atoi(currentHour.Format("2006010215")) // 上一个小时的起始时间 lastHour := currentHour.Add(-time.Hour * 1) lastHourInt, _ := strconv.Atoi(lastHour.Format("2006010215")) var allHourConsumeCoinFloat float64 for orgID, wxinfos := range wxbotsSet { var orgHourConsumeCoinFloat float64 for _, wxinfo := range wxinfos { l.Logger.Infof("开始计算小时数据:%d\n", lastHourInt) // 先判断该账号是否已经统计了小时数据,如果已经统计了,就不需要再统计了 var consumeCoinFloat float64 // 计算积分消耗 usageDetails, _ := l.svcCtx.DB.UsageDetail.Query().Where( usagedetail.BotID(wxinfo), usagedetail.CreatedAtGTE(lastHour), usagedetail.CreatedAtLT(currentHour), ).Order(ent.Desc(usagedetail.FieldCreatedAt)).All(l.ctx) allHourConsumeCoinFloat += consumeCoinFloat orgHourConsumeCoinFloat += consumeCoinFloat for _, usageDetail := range usageDetails { // 更改积分明细表 hourDataCount, _ := l.svcCtx.DB.CreditUsage.Query().Where( creditusage.TableEQ("usage_detail"), creditusage.NidEQ(usageDetail.ID), ).Count(l.ctx) if hourDataCount == 0 { balanceSet[orgID] += usageDetail.Credits _, err = l.svcCtx.DB.CreditUsage.Create(). SetNotNilNumber(&usageDetail.Credits). SetNtype(1). SetTable("usage_detail"). SetOrganizationID(orgID). SetNid(usageDetail.ID). Save(l.ctx) l.Errorf("save hour data error:%v \n", err) } } } } } for orgID, balance := range balanceSet { hourDataCount, _ := l.svcCtx.DB.CreditBalance.Query().Where( creditbalance.OrganizationIDEQ(orgID), ).Count(l.ctx) if hourDataCount == 0 { _, err = l.svcCtx.DB.CreditBalance.Create(). SetBalance(balance). SetOrganizationID(orgID). Save(l.ctx) l.Errorf("save hour data error:%v \n", err) } else { _, err = l.svcCtx.DB.CreditBalance.Update(). Where(creditbalance.OrganizationIDEQ(orgID)). SetBalance(balance). Save(l.ctx) l.Errorf("save hour data error:%v \n", err) } } return }