|
@@ -9,6 +9,8 @@ import (
|
|
|
"strings"
|
|
|
"time"
|
|
|
|
|
|
+ "gorm.io/gorm"
|
|
|
+
|
|
|
"gitee.com/xuyiping_admin/pkg/logger/zaplog"
|
|
|
"go.uber.org/zap"
|
|
|
)
|
|
@@ -32,21 +34,27 @@ func (e *Entry) ProcessMilkOriginal(pastureId int64) {
|
|
|
zaplog.Error("MilkOriginal", zap.Any("pastureId", pastureId), zap.Any("err", err))
|
|
|
return
|
|
|
}
|
|
|
+ shifts := make([]int32, 0)
|
|
|
milkClassConfig := &MilkClassConfig{}
|
|
|
for _, v := range milkConfigList {
|
|
|
switch v.Name {
|
|
|
case model.FirstClassMilkTime:
|
|
|
milkClassConfig.FirstClassMilkTime = v.Value
|
|
|
+ shifts = append(shifts, 1)
|
|
|
case model.SecondClassMilkTime:
|
|
|
milkClassConfig.SecondClassMilkTime = v.Value
|
|
|
+ shifts = append(shifts, 2)
|
|
|
case model.ThirdClassMilkTime:
|
|
|
milkClassConfig.ThirdClassMilkTime = v.Value
|
|
|
+ shifts = append(shifts, 3)
|
|
|
case model.FourthClassMilkTime:
|
|
|
milkClassConfig.FourthClassMilkTime = v.Value
|
|
|
+ shifts = append(shifts, 4)
|
|
|
case model.UpdateMilkOriginalMaxId:
|
|
|
maxId, _ := strconv.ParseInt(v.Value, 10, 64)
|
|
|
milkClassConfig.OldUpdateMaxId = maxId
|
|
|
}
|
|
|
+
|
|
|
}
|
|
|
xDBeg, xBeg1, xBeg2, xBeg3, xBeg4 := parseXBeg(milkClassConfig)
|
|
|
e.UpdateShifts(pastureId, xBeg1, xBeg2, xBeg3, xBeg4)
|
|
@@ -86,11 +94,13 @@ func (e *Entry) ProcessMilkOriginal(pastureId int64) {
|
|
|
return
|
|
|
}
|
|
|
|
|
|
+ milkHallList := e.FindMilkHallList(pastureId)
|
|
|
e.DeleteRepeatMilkData(pastureId, deleteModel, milkClassConfig, milkOriginalList)
|
|
|
- e.MilkHallData(pastureId)
|
|
|
+ e.UpdateRecognitionTime(pastureId, milkHallList)
|
|
|
e.UpdateRepeatCupSet1(milkOriginalList)
|
|
|
- e.UpdateMilkOriginCowInfo(milkOriginalList)
|
|
|
+ e.UpdateMilkOriginCowInfo(milkOriginalList, milkHallList)
|
|
|
e.UpdateRepeatCupSet2(milkOriginalList)
|
|
|
+ e.UpdateMilkOriginalInitialTimesAndAttachAdjustTime(shifts, milkOriginalList)
|
|
|
}
|
|
|
|
|
|
// UpdateShifts 更新班次
|
|
@@ -219,44 +229,38 @@ func (e *Entry) DeleteRepeatMilkData(pastureId int64, deleteModel *DeleteMilkOri
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-func (e *Entry) MilkHallData(pastureId int64) {
|
|
|
- milkHallList := e.FindMilkHallList(pastureId)
|
|
|
+// UpdateRecognitionTime 识别时间超过40分钟未套杯牛只,识别改为未识别
|
|
|
+func (e *Entry) UpdateRecognitionTime(pastureId int64, milkHallList []*model.MilkHall) {
|
|
|
if len(milkHallList) == 0 {
|
|
|
return
|
|
|
}
|
|
|
+ for _, hall := range milkHallList {
|
|
|
+ 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 milkHallList {
|
|
|
- e.UpdateRecognitionTime(pastureId, v)
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-// 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())
|
|
|
+ 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))
|
|
|
+ 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))
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
}
|
|
@@ -298,8 +302,186 @@ func (e *Entry) UpdateRepeatCupSet1(milkOriginalList []*model.MilkOriginal) {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-func (e *Entry) UpdateMilkOriginCowInfo(milkOriginalList []*model.MilkOriginal) {
|
|
|
+// UpdateMilkOriginCowInfo 更新牛只信息
|
|
|
+func (e *Entry) UpdateMilkOriginCowInfo(milkOriginalList []*model.MilkOriginal, milkHallList []*model.MilkHall) {
|
|
|
+ milkHallMap := make(map[string][]*model.MilkOriginal)
|
|
|
+ for _, v := range milkOriginalList {
|
|
|
+ key := fmt.Sprintf("%s", v.MilkHallNumber)
|
|
|
+ milkHallMap[key] = append(milkHallMap[key], v)
|
|
|
+ }
|
|
|
+
|
|
|
+ for _, v := range milkHallList {
|
|
|
+ dataList, ok := milkHallMap[v.Name]
|
|
|
+ if !ok {
|
|
|
+ continue
|
|
|
+ }
|
|
|
+ switch v.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.DetacherTime == "" {
|
|
|
+ continue
|
|
|
+ }
|
|
|
+ if shiftMinDetachTimes == "" {
|
|
|
+ shiftMinDetachTimes = m.DetacherTime
|
|
|
+ } else {
|
|
|
+ t1, _ := util.TimeParseLocal(model.LayoutTime, m.DetacherTime)
|
|
|
+ t2, _ := util.TimeParseLocal(model.LayoutTime, shiftMinDetachTimes)
|
|
|
+ if t2.Before(t1) {
|
|
|
+ shiftMinDetachTimes = m.DetacherTime
|
|
|
+ }
|
|
|
+ }
|
|
|
+ addressMap[m.DetacherAddress] = append(addressMap[m.DetacherAddress], 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].DetacherAddress != list[j].DetacherAddress {
|
|
|
+ return list[i].DetacherAddress < list[j].DetacherAddress
|
|
|
+ }
|
|
|
+ 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.DetacherAddress != lastAddress {
|
|
|
+ initialTimeStr = b5
|
|
|
+ } else {
|
|
|
+ // 否则使用上一条记录的脱杯时间
|
|
|
+ initialTimeStr = lastDetachTime
|
|
|
+ }
|
|
|
|
|
|
+ // 更新最后记录的地址和时间
|
|
|
+ lastAddress = m.DetacherAddress
|
|
|
+ lastDetachTime = m.DetacherTime
|
|
|
+
|
|
|
+ // 只有当initialTime不为空且与原有值不同时才需要更新
|
|
|
+ if initialTimeStr != "" {
|
|
|
+ initialTime, _ := util.TimeParseLocal(model.LayoutTime, initialTimeStr)
|
|
|
+ attachTime, _ := util.TimeParseLocal(model.LayoutTime, m.AttachTime)
|
|
|
+ detachTime, _ := util.TimeParseLocal(model.LayoutTime, m.DetacherTime)
|
|
|
+
|
|
|
+ // 条件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 非标准重复套杯
|
|
@@ -308,9 +490,9 @@ func (e *Entry) UpdateRepeatCupSet2(milkOriginalList []*model.MilkOriginal) {
|
|
|
if v.AttachTime == "" || v.InitialTime == "" {
|
|
|
continue
|
|
|
}
|
|
|
- attchTime, _ := util.TimeParseLocal(model.LayoutTime, v.AttachTime)
|
|
|
+ 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 && attchTime.Sub(initialTime).Minutes() <= 1 {
|
|
|
+ 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).
|