package crontab import ( "kpt-pasture/model" "kpt-pasture/util" "time" "gitee.com/xuyiping_admin/pkg/xerr" pasturePb "gitee.com/xuyiping_admin/go_proto/proto/go/backend/cow" "gitee.com/xuyiping_admin/pkg/logger/zaplog" "go.uber.org/zap" ) func (e *Entry) InsertMilkDaily() error { pastureList := e.FindPastureList() if pastureList == nil || len(pastureList) == 0 { return nil } for _, pasture := range pastureList { // 获取最大记录日期或默认日期 pastureId := pasture.Id var maxDateTime string if err := e.DB.Model(new(model.MilkDaily)). Where("pasture_id = ?", pastureId). Select("IFNULL(MAX(heat_date) + INTERVAL 1 DAY, CURDATE() - INTERVAL 1 MONTH) AS max_date_time"). Scan(&maxDateTime).Error; err != nil { zaplog.Error("InsertMilkDaily", zap.Any("pastureId", pastureId), zap.Any("err", err)) continue } maxDate, err := util.TimeParseLocal(model.LayoutDate2, maxDateTime) if err != nil { zaplog.Error("InsertMilkDaily", zap.Any("pastureId", pastureId), zap.Any("err", err)) continue } e.ProcessMilkDaily(pastureId, maxDate) } return nil } func (e *Entry) ProcessMilkDaily(pastureId int64, maxDate time.Time) { nowTime := time.Now().Local() // 处理每一天的数据 for maxDate.Before(nowTime) { // 处理有胎次的奶牛 processCowIds := make([]int64, 0) cowIds, err := e.processCowsWithLact(pastureId, maxDate) if err != nil { zaplog.Error("ProcessMilkDaily", zap.Any("processCowsWithFetal", err)) } if len(cowIds) > 0 { processCowIds = append(processCowIds, cowIds...) } // 处理无胎次的奶牛 cowIds, err = e.processCowsWithNoLact(pastureId, maxDate) if err != nil { zaplog.Error("ProcessMilkDaily", zap.Any("processCowsWithoutFetal", err)) } if len(cowIds) > 0 { processCowIds = append(processCowIds, cowIds...) } if len(processCowIds) > 0 { e.UpdateMilkDaily(pastureId, processCowIds, maxDate.Format(model.LayoutDate2)) } // 日期加1天 maxDate = maxDate.AddDate(0, 0, 1) } } // UpdateMilkDaily // SELECT h.intCowId, ROUND(AVG(h.filterhigh), 0) high, ROUND(AVG( h.rumina)*12, 0) rumina, ROUND(AVG( h.intake)*12, 0) intake, // // ROUND(AVG( h.inactive)*12, 0) inactive, ROUND(AVG( h.act)*12, 0) act, COUNT(1) nb // // FROM h_activehabit h WHERE h.intPastureId=PastuId AND h.heatdate=xDate GROUP BY h.intCowId HAVING nb>=8 func (e *Entry) UpdateMilkDaily(pastureId int64, processCowIds []int64, heatDate string) error { neckActiveHabitList := make([]*model.NeckActiveHabit, 0) if err := e.DB.Model(new(model.NeckActiveHabit)). Select(`cow_id, ROUND(AVG(filter_high), 0) AS high, ROUND(AVG(rumina)*12, 0) AS rumina, ROUND(AVG(intake)*12, 0) AS intake, ROUND(AVG(inactive)*12, 0) AS inactive, ROUND(AVG(active)*12, 0) AS active, COUNT(1) AS record_count`). Where("pasture_id = ?", pastureId). Where("cow_id IN ?", processCowIds). Where("heat_date = ?", heatDate). Group("cow_id"). Find(&neckActiveHabitList).Error; err != nil { return xerr.WithStack(err) } for _, v := range neckActiveHabitList { // todo 先不过滤 /*if v.RecordCount < 8 { continue }*/ if err := e.DB.Model(new(model.MilkDaily)). Where("pasture_id = ?", pastureId). Where("cow_id = ?", v.CowId). Where("heat_date = ?", heatDate). Updates(map[string]interface{}{ "day_high": v.High, "day_rumina": v.Rumina, "day_intake": v.Intake, "day_inactive": v.Inactive, "day_active": v.Active, }).Error; err != nil { zaplog.Error("UpdateMilkDaily", zap.Any("pastureId", pastureId), zap.Any("cowId", v.CowId), zap.Any("heatDate", heatDate), zap.Any("err", err)) continue } } return nil } // 处理有胎次的奶牛 func (e *Entry) processCowsWithLact(pastureId int64, recordDate time.Time) ([]int64, error) { // 查询有胎次且在记录日期前有记录的奶牛 cowList := make([]*model.Cow, 0) if err := e.DB.Model(new(model.Cow)). Where("pasture_id = ?", pastureId). Where("admission_status = ?", pasturePb.AdmissionStatus_Admission). Where("lact > ?", 0). Where("last_calving_at <= ?", recordDate.Local().Unix()). Find(&cowList).Error; err != nil { return nil, err } // 批量插入数据 milkDailyList := make([]*model.MilkDaily, 0) cowIds := make([]int64, 0) for _, cow := range cowList { calvingDate := "" if cow.LastCalvingAt > 0 { calvingDate = time.Unix(cow.LastCalvingAt, 0).Local().Format(model.LayoutDate2) } milkDaily := &model.MilkDaily{ CowId: cow.Id, Lact: cow.Lact, PastureId: cow.PastureId, EarNumber: cow.EarNumber, CalvingDate: calvingDate, HeatDate: recordDate.Format(model.LayoutDate2), LactationAge: cow.LactationAge, PenId: cow.PenId, PenName: cow.PenName, BreedStatus: cow.BreedStatus, } milkDailyList = append(milkDailyList, milkDaily) cowIds = append(cowIds, cow.Id) } if len(milkDailyList) > 0 { // 分批次插入数据 for i := 0; i < len(milkDailyList); i += 100 { end := i + 100 if end > len(milkDailyList) { end = len(milkDailyList) } if err := e.DB.Model(new(model.MilkDaily)). Create(milkDailyList[i:end]).Error; err != nil { return nil, err } } } return cowIds, nil } // 处理无胎次的奶牛 func (e *Entry) processCowsWithNoLact(pastureId int64, recordDate time.Time) ([]int64, error) { // 查询无胎次且EID1>0的奶牛 cowList := make([]*model.Cow, 0) err := e.DB.Model(new(model.Cow)). //Select("c.intCowId as cow_id, c.intPastureId as pasture_id, c.varCowCode as cow_code,c.dateBirthDate as birth_date, c.intCurBar as cur_bar"). //Where("(c.dateLeave IS NULL OR c.dateLeave > ?) AND c.intCurFetal = 0 AND c.EID1 > 0", recordDate). Where("pasture_id = ?", pastureId). Where("admission_status = ?", pasturePb.AdmissionStatus_Admission). Where("lact = ?", 0). Where("neck_ring_number != ?", ""). Find(&cowList).Error if err != nil { return nil, err } // 批量插入数据 milkDailyList := make([]*model.MilkDaily, 0) cowIds := make([]int64, 0) for _, cow := range cowList { birthDate, calvingDate := "", "" if cow.BirthAt > 0 { birthDate = time.Unix(cow.BirthAt, 0).Local().Format(model.LayoutDate2) } if cow.LastCalvingAt > 0 { calvingDate = time.Unix(cow.LastCalvingAt, 0).Local().Format(model.LayoutDate2) } milkDaily := &model.MilkDaily{ CowId: cow.Id, Lact: cow.Lact, PastureId: cow.PastureId, EarNumber: cow.EarNumber, BirthDate: birthDate, CalvingDate: calvingDate, LactationAge: cow.LactationAge, HeatDate: recordDate.Format(model.LayoutDate2), PenId: cow.PenId, PenName: cow.PenName, BreedStatus: cow.BreedStatus, } milkDailyList = append(milkDailyList, milkDaily) cowIds = append(cowIds, cow.Id) } if len(milkDailyList) > 0 { if err = e.DB.Model(new(model.MilkDaily)). Create(&milkDailyList).Error; err != nil { return nil, err } } return cowIds, nil }