| 
					
				 | 
			
			
				@@ -0,0 +1,493 @@ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+package crontab 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+import ( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	"fmt" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	"kpt-pasture/model" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	"kpt-pasture/util" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	"sort" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	"strings" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	"time" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	"gorm.io/gorm" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	"gitee.com/xuyiping_admin/pkg/logger/zaplog" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	"go.uber.org/zap" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+// UpdateRecognitionTime 识别时间超过40分钟未套杯牛只,识别改为未识别 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+func (e *Entry) UpdateRecognitionTime(pastureId int64, hall *model.MilkHall) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	milkOriginalList := make([]*model.MilkOriginal, 0) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	if err := e.DB.Model(new(model.MilkOriginal)). 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		Where("pasture_id = ?", pastureId). 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		Where("milk_hall_number = ?", hall.Name). 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		Where("milk_hall_brand = ?", hall.Brand). 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		Where("load = ?", 0). 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		Find(&milkOriginalList).Error; err != nil { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		zaplog.Error("MilkHallData", zap.Any("err", err)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	for _, v := range milkOriginalList { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		t1, _ := util.TimeParseLocal(model.LayoutTime, v.AttachTime) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		t2, _ := util.TimeParseLocal(model.LayoutTime, v.RecognitionTime) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		diff := t1.Sub(t2) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		minute := int(diff.Minutes()) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		if util.Substr(v.RecognitionTime, -1, 8) != "00:00:00" && minute > 40 { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			if err := e.DB.Model(new(model.MilkOriginal)). 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				Where("id = ?", v.Id). 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				Updates(map[string]interface{}{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+					"cow_id":           0, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+					"ele_ear_number":   "", 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+					"recognition_time": fmt.Sprintf("%s 00:00:00", util.Substr(v.RecognitionTime, 0, 10)), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				}).Error; err != nil { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				zaplog.Error("MilkHallData", zap.Any("err", err)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+// UpdateRepeatCupSet1 更新重复套杯1, 识别时间相同,且不为0为重复套杯 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+func (e *Entry) UpdateRepeatCupSet1(milkOriginalList []*model.MilkOriginal) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	if len(milkOriginalList) == 0 { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		return 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	milkOriginalMap := make(map[string][]*model.MilkOriginal) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	for _, v := range milkOriginalList { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		if strings.HasSuffix(v.RecognitionTime, "00:00:00") { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			continue 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		key := fmt.Sprintf("%s_%d_%d_%s", v.MilkDate, v.Shifts, v.DetachedAddress, v.RecognitionTime) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		milkOriginalMap[key] = append(milkOriginalMap[key], v) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	for _, originalList := range milkOriginalMap { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		if len(originalList) >= 2 { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			// 按照Id升序排序(保留第一条) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			sort.Slice(originalList, func(i, j int) bool { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				return originalList[i].Id < originalList[j].Id 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			}) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			for i, v := range originalList { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				if i == 0 { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+					continue 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				if err := e.DB.Model(new(model.MilkOriginal)). 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+					Select("").Where("id = ?", v.Id). 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+					Update("nattach", 2).Error; err != nil { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+					zaplog.Error("UpdateRepeatCupSet1", zap.Any("err", err)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+// UpdateMilkOriginCowInfo 更新牛只信息 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+func (e *Entry) UpdateMilkOriginCowInfo(milkOriginalList []*model.MilkOriginal, hall *model.MilkHall) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	milkHallMap := make(map[string][]*model.MilkOriginal) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	for _, v := range milkOriginalList { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		key := fmt.Sprintf("%s", v.MilkHallNumber) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		milkHallMap[key] = append(milkHallMap[key], v) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	dataList, ok := milkHallMap[hall.Name] 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	if !ok { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		return 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	switch hall.IsExtraUpdate { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	case model.IsExtra0: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	case model.IsExtra1, model.IsExtra3: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		for _, d := range dataList { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			if d.EarNumber == "" { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				continue 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			cowInfo, err := e.GetCowByEarNumber(d.PastureId, d.EarNumber) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			if err != nil { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				zaplog.Error("UpdateMilkOriginCowInfo", zap.Any("err", err), zap.Any("data", d)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				continue 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			// 更新牛只信息 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			d.UpdateCowInfo(cowInfo) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			if err = e.DB.Model(new(model.MilkOriginal)). 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				Select("cow_id", "pen_id", "pen_name"). 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				Where("id = ?", d.Id).Updates(d).Error; err != nil { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				zaplog.Error("UpdateMilkOriginCowInfo", zap.Any("err", err), zap.Any("data", d)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	case model.IsExtra2: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	default: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+func (e *Entry) UpdateMilkOriginalInitialTimesAndAttachAdjustTime(shifts []int32, milkOriginalList []*model.MilkOriginal) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	for _, shift := range shifts { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		shiftMinDetachTimes := "" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		// 按脱杯地址分组处理 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		addressMap := make(map[int64][]*model.MilkOriginal) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		for _, m := range milkOriginalList { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			if m.Shifts != shift || m.DetachedTime == "" { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				continue 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			if shiftMinDetachTimes == "" { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				shiftMinDetachTimes = m.DetachedTime 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			} else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				t1, _ := util.TimeParseLocal(model.LayoutTime, m.DetachedTime) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				t2, _ := util.TimeParseLocal(model.LayoutTime, shiftMinDetachTimes) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				if t2.Before(t1) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+					shiftMinDetachTimes = m.DetachedTime 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			addressMap[m.DetachedAddress] = append(addressMap[m.DetachedAddress], m) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		if shiftMinDetachTimes == "" { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			continue 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		bt, _ := util.TimeParseLocal(model.LayoutTime, shiftMinDetachTimes) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		b5 := bt.Add(-5*time.Minute).Format(model.LayoutHour) + "00:00" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		for _, list := range addressMap { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			// 对当前地址的记录按时间排序 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			sort.Slice(list, func(i, j int) bool { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				if list[i].MilkDate != list[j].MilkDate { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+					return list[i].MilkDate < list[j].MilkDate 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				if list[i].Shifts != list[j].Shifts { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+					return list[i].Shifts < list[j].Shifts 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				if list[i].DetachedAddress != list[j].DetachedAddress { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+					return list[i].DetachedAddress < list[j].DetachedAddress 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				return list[i].Id < list[j].Id 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			}) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			// 初始化变量,模拟SQL中的@address和@det 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			var lastAddress int64 = 0 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			var lastDetachTime string = "2001-01-01 06:00:00" // 默认初始值 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			// 批量更新参数 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			var updateParams []struct { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				ID           int64 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				InitialTimes string 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				AttachAdjust string 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			for _, m := range list { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				var initialTimeStr string 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				var attachAdjust string 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				// 如果当前记录的脱杯地址与上一条不同,则使用基准时间b5 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				if m.DetachedAddress != lastAddress { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+					initialTimeStr = b5 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				} else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+					// 否则使用上一条记录的脱杯时间 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+					initialTimeStr = lastDetachTime 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				// 更新最后记录的地址和时间 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				lastAddress = m.DetachedAddress 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				lastDetachTime = m.DetachedTime 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				// 只有当initialTime不为空且与原有值不同时才需要更新 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				if initialTimeStr != "" { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+					initialTime, _ := util.TimeParseLocal(model.LayoutTime, initialTimeStr) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+					attachTime, _ := util.TimeParseLocal(model.LayoutTime, m.AttachTime) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+					detachTime, _ := util.TimeParseLocal(model.LayoutTime, m.DetachedTime) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+					// 条件1:attachtimes以'00:00:00'结尾或attachtimes <= initialtimes 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+					if strings.HasSuffix(m.AttachTime, "00:00:00") || attachTime.Before(initialTime) || attachTime.Equal(initialTime) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+						// 计算 detachtimes - (1.5 + duration)*60 秒 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+						adjustTime1 := detachTime.Add(-time.Duration((90 + m.Duration*60)) * time.Second) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+						// 取三者中的最大值 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+						maxTime := util.FindMaxTime(attachTime, initialTime, adjustTime1) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+						attachAdjust = maxTime.Format(model.LayoutTime) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+					} else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+						// 计算 detachtimes - duration*60 秒 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+						adjustTime2 := detachTime.Add(-time.Duration(m.Duration*60) * time.Second) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+						// 取 attachtimes 和 adjustTime2 中的较小值 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+						minTime := util.FindMinTime(attachTime, adjustTime2) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+						// 再与 initialtimes 取较大值 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+						maxTime := util.FindMaxTime(minTime, initialTime) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+						attachAdjust = maxTime.Format(model.LayoutTime) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+					} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+					// 记录需要更新的字段 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+					updateParams = append(updateParams, struct { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+						ID           int64 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+						InitialTimes string 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+						AttachAdjust string 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+					}{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+						ID:           m.Id, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+						InitialTimes: initialTimeStr, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+						AttachAdjust: attachAdjust, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+					}) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+					/*if err := e.DB.Model(new(model.MilkOriginal)). 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+						Select("initial_time"). 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+						Where("id = ?", m.Id). 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+						Update("initial_time", initialTime).Error; err != nil { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+						zaplog.Error("UpdateMilkOriginalInitialTimesAndAttachAdjustTime", zap.Any("err", err)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+					}*/ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			if len(updateParams) > 0 { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				// 批量更新数据库 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				if err := e.DB.Transaction(func(tx *gorm.DB) error { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+					for _, param := range updateParams { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+						updates := map[string]interface{}{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+							"initial_times":      param.InitialTimes, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+							"attach_adjust_time": param.AttachAdjust, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+						} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+						if err := tx.Model(new(model.MilkOriginal)). 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+							Select("initial_time", "attach_adjust_time"). 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+							Where("id = ? ", param.ID). 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+							Updates(updates).Error; err != nil { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+							return err 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+						} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+					} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+					return nil 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				}); err != nil { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+					zaplog.Error("UpdateMilkOriginalInitialTimesAndAttachAdjustTime", zap.Any("err", err)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+// UpdateRepeatCupSet2  非标准重复套杯 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+func (e *Entry) UpdateRepeatCupSet2(milkOriginalList []*model.MilkOriginal) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	for _, v := range milkOriginalList { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		if v.AttachTime == "" || v.InitialTime == "" { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			continue 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		nattchTime, _ := util.TimeParseLocal(model.LayoutTime, v.AttachTime) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		initialTime, _ := util.TimeParseLocal(model.LayoutTime, v.InitialTime) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		if util.Substr(v.InitialTime, -1, 5) != "00:00" && v.Nattach == 0 && nattchTime.Sub(initialTime).Minutes() <= 1 { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			if err := e.DB.Model(new(model.MilkOriginal)). 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				Select("nattach"). 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				Where("id = ?", v.Id). 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				Update("nattach", 2).Error; err != nil { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				zaplog.Error("UpdateRepeatCupSet2", zap.Any("err", err)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+// UpdateMilkNattach 非标准重复套杯 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+func (e *Entry) UpdateMilkNattach(pastureId int64, milkClassConfig *MilkClassConfig, hall *model.MilkHall) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	milkOriginalList := make([]*model.MilkOriginal, 0) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	if err := e.DB.Model(new(model.MilkOriginal)). 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		Where("pasture_id = ?", pastureId). 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		Where("id BETWEEN ? AND ?", milkClassConfig.OldUpdateMaxId+1, milkClassConfig.CurrentMaxId). 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		Find(&milkOriginalList).Error; err != nil { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		zaplog.Error("DeleteRepeatMilkData", zap.Any("pastureId", pastureId), zap.Any("err", err)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		return 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	for _, v := range milkOriginalList { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		if v.InitialTime == "" || v.AttachTime == "" { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			continue 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		attachTime, _ := util.TimeParseLocal(model.LayoutTime, v.AttachTime) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		initialTime, _ := util.TimeParseLocal(model.LayoutTime, v.InitialTime) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		initialTimePlus1Min := initialTime.Add(time.Minute) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		if hall.Brand == v.MilkHallBrand && hall.Name == v.MilkHallNumber && v.Nattach == 0 && 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			!strings.HasSuffix(v.InitialTime, "00:00") && (attachTime.Before(initialTimePlus1Min) || attachTime.Equal(initialTimePlus1Min)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			if err := e.DB.Model(new(model.MilkOriginal)). 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				Select("nattach"). 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				Where("id = ?", v.Id). 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				Update("nattach", 2).Error; err != nil { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				zaplog.Error("UpdateMilkNattach", zap.Any("err", err)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+// UpdateMilkNoCowId 清理无牛号牛只:重复超过2圈牛号,套杯时间间隔大于17分钟 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+func (e *Entry) UpdateMilkNoCowId(pastureId int64, milkClassConfig *MilkClassConfig, hall *model.MilkHall) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	//  SELECT 	m2.wid 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	//	FROM (SELECT m0.milkdate, m0.shifts, m0.detacher_address, m0.cow_id, MIN(m0.wid) wid, COUNT(0) nb, MIN(m0.attachtimes) attachtimes 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	//	FROM milkweight m0 WHERE m0.wid BETWEEN xdminwid AND xdmaxwid AND m0.milkdate=xcurdate AND m0.cow_id>0 AND m0.station=xvarName 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	//	GROUP BY m0.shifts, m0.detacher_address, m0.cow_id HAVING nb>1) m1 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	//	JOIN milkweight m2 ON m1.milkdate=m2.milkdate AND m1.shifts=m2.shifts AND m2.station=xvarName AND m1.detacher_address=m2.detacher_address 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	//	AND m1.cow_id=m2.cow_id AND m1.wid<m2.wid WHERE m2.wid BETWEEN xdminwid AND xdmaxwid AND m2.milkdate=xcurdate AND m2.cow_id>0 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	//	AND (m1.attachtimes + INTERVAL 17 MINUTE) < m2.attachtimes ; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	minMilkOriginalRecordsList := make([]*model.MinMilkOriginalRecords, 0) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	if err := e.DB.Model(new(model.MilkOriginal)). 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		Select("MIN(id) AS min_id, COUNT(0) AS count, cow_id, detached_address, milk_date, MIN(attach_time) AS min_attach_time"). 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		Where("pasture_id = ?", pastureId). 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		Where("id BETWEEN ? AND ?", milkClassConfig.OldUpdateMaxId+1, milkClassConfig.CurrentMaxId). 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		Where("cow_id > ?", 0). 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		Where("milk_hall_number = ?", hall.Name). 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		Group("shifts, detached_address, cow_id"). 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		Having("count > ? AND min_attach_time != ?", 1, ""). 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		Find(&minMilkOriginalRecordsList).Error; err != nil { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		zaplog.Error("UpdateMilkNoCowId", zap.Any("err", err)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		return 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	// 2. 收集需要更新的 id 列表 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	idsToUpdate := make([]int64, 0) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	for _, v := range minMilkOriginalRecordsList { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		var laterRecords []struct { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			Id int64 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		attachTime, _ := util.TimeParseLocal(model.LayoutTime, v.MinAttachTime) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		attachTimeAdd17 := attachTime.Add(time.Minute * 17).Format(model.LayoutTime) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		if err := e.DB.Model(new(model.MilkOriginal)). 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			Select("id"). 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			Where("pasture_id = ?", pastureId). 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			Where("id BETWEEN ? AND ?", milkClassConfig.OldUpdateMaxId+1, milkClassConfig.CurrentMaxId). 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			Where("cow_id = ?", v.CowId). 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			Where("detached_address = ?", v.DetachedAddress). 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			Where("milk_date = ?", v.MilkDate). 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			Where("attach_time > ?", attachTimeAdd17).Find(&laterRecords).Error; err != nil { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			zaplog.Error("UpdateMilkNoCowId", zap.Any("err", err)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			continue 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		if len(laterRecords) > 0 { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			idsToUpdate = append(idsToUpdate, v.MinId) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	if len(idsToUpdate) > 0 { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		if err := e.DB.Model(new(model.MilkOriginal)). 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			Where("id IN ?", idsToUpdate). 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			Updates(map[string]interface{}{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				"cow_id":     0, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				"ear_number": "", 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				"pen_id":     0, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				"pen_name":   "", 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			}).Error; err != nil { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			zaplog.Error("UpdateMilkNoCowId", zap.Any("err", err)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+// UpdateMilkLoad 设置批次 圈数 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+func (e *Entry) UpdateMilkLoad(pastureId int64, milkClassConfig *MilkClassConfig, hall *model.MilkHall) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	var ( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		xAddress = int32(999) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		//xShift          = 6 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		xLoad           = int32(0) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		recognitionTime = time.Date(2001, 1, 1, 1, 1, 1, 0, time.Local) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	baseRecords := make([]*model.BaseRecords, 0) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	if err := e.DB.Model(new(model.MilkOriginal)). 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		Select("id,attach_adjust,detached_address,shifts,ear_number,milk_date,recognition_time"). 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		Where("pasture_id = ?", pastureId). 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		Where("id BETWEEN ? AND ?", milkClassConfig.OldUpdateMaxId+1, milkClassConfig.CurrentMaxId). 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		Where("nattach = ?", 0).Where("milk_hall_number = ?", hall.Name). 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		Order("attach_adjust,detached_address"). 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		Limit(99).Find(&baseRecords).Error; err != nil { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		zaplog.Error("UpdateMilkLoad", zap.Any("err", err)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		return 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	// 3. 处理每条记录并计算 load 值 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	recordsToUpdate := make([]*model.UpdateLoadRecord, 0) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	for _, record := range baseRecords { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		if record.RecognitionTime != "" && record.AttachAdjust != "" { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			r, _ := util.TimeParseLocal(model.LayoutTime, record.RecognitionTime) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			a, _ := util.TimeParseLocal(model.LayoutTime, record.AttachAdjust) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			diff := int32(a.Sub(r).Minutes()) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			if !(diff >= 0 && diff <= 15 && !strings.HasSuffix(record.RecognitionTime, "00:00:00")) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				record.RecognitionTime = record.AttachAdjust 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		r, _ := util.TimeParseLocal(model.LayoutTime, record.RecognitionTime) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		/*var maxLoad int32 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		if (record.DetachedAddress < xAddress-27 && r.After(recognitionTime.Add(-5*time.Minute))) || record.Shifts > xShift || r.After(recognitionTime.Add(6*time.Minute)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			xLoad++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			maxLoad = xLoad 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		} else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			maxLoad = xLoad 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		}*/ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		// 计算 currentLoad 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		var currentLoad int32 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		if (xAddress+60-record.DetachedAddress <= 27) && 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			r.Before(recognitionTime.Add(3*time.Minute)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			currentLoad = maxInt(xLoad-1, 1) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		} else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			currentLoad = xLoad 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		// 更新地址 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		if (xAddress+60-record.DetachedAddress <= 27) && 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			r.Before(recognitionTime.Add(3*time.Minute)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			// 保持原地址 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		} else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			xAddress = record.DetachedAddress 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		// 更新shift和时间 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		//xShift = record.Shifts 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		if r.After(recognitionTime) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			recognitionTime = r 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		// 记录需要更新的数据 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		recordsToUpdate = append(recordsToUpdate, &model.UpdateLoadRecord{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			Id:   record.Id, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			Load: currentLoad, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		}) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	if len(recordsToUpdate) > 0 { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		batchSize := 100 // 每批更新100条 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		for i := 0; i < len(recordsToUpdate); i += batchSize { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			end := i + batchSize 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			if end > len(recordsToUpdate) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				end = len(recordsToUpdate) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			batch := recordsToUpdate[i:end] 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			if err := e.DB.Model(new(model.MilkOriginal)). 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				Where("id IN (?)", getWIDsFromUpdateRecords(batch)). 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				Updates(map[string]interface{}{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+					"load": gorm.Expr("CASE id " + buildCaseWhen(batch) + " END"), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				}).Error; err != nil { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				zaplog.Error("UpdateMilkLoad", zap.Any("err", err)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				continue 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+// 辅助函数:从更新记录中提取WID列表 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+func getWIDsFromUpdateRecords(records []*model.UpdateLoadRecord) []int64 { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	ids := make([]int64, len(records)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	for i, r := range records { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		ids[i] = r.Id 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	return ids 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+// 辅助函数:构建CASE WHEN语句 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+func buildCaseWhen(records []*model.UpdateLoadRecord) string { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	var builder strings.Builder 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	for _, r := range records { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		builder.WriteString(fmt.Sprintf("WHEN %d THEN %d ", r.Id, r.Load)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	builder.WriteString("ELSE load") 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	return builder.String() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+// 辅助函数:返回两个整数中的最大值 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+func maxInt(a, b int32) int32 { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	if a > b { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		return a 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	return b 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 |