package backend import ( "context" "fmt" "kpt-pasture/model" "kpt-pasture/util" "net/http" "time" "go.uber.org/zap" "gorm.io/gorm" pasturePb "gitee.com/xuyiping_admin/go_proto/proto/go/backend/cow" "gitee.com/xuyiping_admin/pkg/logger/zaplog" "gitee.com/xuyiping_admin/pkg/xerr" ) func (s *StoreEntry) NeckRingWarningEstrusOrAbortionCowList(ctx context.Context, req *pasturePb.WarningItemsRequest, pagination *pasturePb.PaginationModel) (*pasturePb.EstrusResponse, error) { userModel, err := s.GetUserModel(ctx) if err != nil { return nil, xerr.WithStack(err) } var count int64 neckRingEstrusList := make([]*model.NeckRingEstrusWarning, 0) var pref *gorm.DB switch req.Kind { case "abortion": pref, err = s.AbortionWarningQuery(ctx, userModel.AppPasture.Id) if err != nil { return nil, xerr.WithStack(err) } default: pref, err = s.EstrusWarningQuery(ctx, userModel.AppPasture.Id) if err != nil { return nil, xerr.WithStack(err) } } if len(req.EarNumber) > 0 { pref.Where("a.ear_number = ?", req.EarNumber) } if req.Level > 0 { pref.Where("a.level = ?", req.Level) } if len(req.PenIds) > 0 { pref.Where("b.pen_id IN ?", req.PenIds) } if err = pref.Order("a.level DESC"). Count(&count). Limit(int(pagination.PageSize)). Offset(int(pagination.PageOffset)). Find(&neckRingEstrusList).Error; err != nil { return nil, xerr.WithStack(err) } cowMap := make(map[int64]*model.Cow) eventLogMap := make(map[int64]string) cowIds := make([]int64, 0) for _, v := range neckRingEstrusList { cowIds = append(cowIds, v.CowId) lastEventLog := s.GetCowLastEvent(userModel.AppPasture.Id, v.CowId, pasturePb.EventCategory_Breed) if lastEventLog != nil { eventLogMap[v.CowId] = lastEventLog.EventDescription } } if len(cowIds) > 0 { cowList, _ := s.GetCowInfoByCowIds(ctx, userModel.AppPasture.Id, cowIds) for _, cow := range cowList { cowMap[cow.Id] = cow } } return &pasturePb.EstrusResponse{ Code: http.StatusOK, Msg: "ok", Data: &pasturePb.EstrusData{ List: model.NeckRingEstrusWarningSlice(neckRingEstrusList).ToPB(cowMap, eventLogMap, req.MatingWindowPeriod), Total: int32(count), PageSize: pagination.PageSize, Page: pagination.Page, }, }, nil } func (s *StoreEntry) NeckRingWarningHealthCowList(ctx context.Context, req *pasturePb.HealthWarningRequest, pagination *pasturePb.PaginationModel) (*pasturePb.HealthWarningResponse, error) { userModel, err := s.GetUserModel(ctx) if err != nil { return nil, xerr.WithStack(err) } neckWaringHealthList := make([]*model.NeckRingHealthWarning, 0) pref := s.DB.Table(fmt.Sprintf("%s as a", new(model.NeckRingHealthWarning).TableName())). Joins(fmt.Sprintf("JOIN cow AS b on a.cow_id = b.id")). Where("a.score >= ?", 0). Where("a.is_show = ?", pasturePb.IsShow_Ok). Where("a.pasture_id = ?", userModel.AppPasture.Id) if len(req.PenIds) > 0 { pref.Where("b.pen_id IN ?", req.PenIds) } if len(req.EarNumber) > 0 { pref.Where("a.ear_number = ?", req.EarNumber) } if req.Level > 0 { pref.Where("a.level = ?", req.Level) } var count int64 if err = pref.Order("a.level DESC"). Count(&count). Limit(int(pagination.PageSize)). Offset(int(pagination.PageOffset)). Find(&neckWaringHealthList).Error; err != nil { return nil, xerr.WithStack(err) } warningHealthLevelMap := s.WarningHealthLevelMap() cowMap := make(map[int64]*model.Cow) eventLogMap := make(map[int64]string) cowIds := make([]int64, 0) for _, v := range neckWaringHealthList { cowIds = append(cowIds, v.CowId) lastEventLog := s.GetCowLastEvent(userModel.AppPasture.Id, v.CowId, pasturePb.EventCategory_Breed) if lastEventLog != nil { eventLogMap[v.CowId] = lastEventLog.EventDescription } } if len(cowIds) > 0 { cowList, _ := s.GetCowInfoByCowIds(ctx, userModel.AppPasture.Id, cowIds) for _, cow := range cowList { cowMap[cow.Id] = cow } } return &pasturePb.HealthWarningResponse{ Code: http.StatusOK, Msg: "ok", Data: &pasturePb.HealthWarningData{ Total: int32(count), Page: pagination.Page, PageSize: pagination.PageSize, List: model.NeckRingHealthWarningSlice(neckWaringHealthList).ToPB(warningHealthLevelMap, cowMap, eventLogMap), }, }, nil } func (s *StoreEntry) NeckRingNoEstrusBatch(ctx context.Context, req *pasturePb.NeckRingNoEstrusBatchRequest) error { userModel, err := s.GetUserModel(ctx) if err != nil { return xerr.WithStack(err) } if len(req.EarNumbers) <= 0 { return xerr.Custom("请选择牛号") } nowTime := time.Now().Local() startTime := nowTime.AddDate(0, 0, -1).Format(model.LayoutDate2) endTime := nowTime.AddDate(0, 0, 1).Format(model.LayoutDate2) startTimeUnix := util.TimeParseLocalUnix(startTime) endTimeUnix := util.TimeParseLocalUnix(endTime) startTime = time.Unix(startTimeUnix, 0).Local().Format(model.LayoutTime) endTime = time.Unix(endTimeUnix, 0).Local().Format(model.LayoutTime) neckRingEstrusWarningList := make([]*model.NeckRingEstrusWarning, 0) if err = s.DB.Model(new(model.NeckRingEstrusWarning)). Where("pasture_id = ?", userModel.AppPasture.Id). Where("date_time BETWEEN ? AND ?", startTime, endTime). Where("ear_number IN ?", req.EarNumbers). Where("is_show = ?", pasturePb.IsShow_Ok). Find(&neckRingEstrusWarningList).Error; err != nil { return xerr.WithStack(err) } if len(neckRingEstrusWarningList) <= 0 { return nil } neckRingEstrusIds := make([]int64, 0) for _, v := range neckRingEstrusWarningList { neckRingEstrus := &model.NeckRingEstrus{} if err = s.DB.Model(new(model.NeckRingEstrus)). Where("pasture_id = ?", userModel.AppPasture.Id). Where("id = ?", v.NeckRingEstrusId). Where("is_show = ?", pasturePb.IsShow_Ok). First(neckRingEstrus).Error; err != nil { zaplog.Error("NeckRingNoEstrusBatch", zap.Any("err", err), zap.Any("neckRingEstrusWarning", v)) return xerr.Customf("数据异常: %s", v.EarNumber) } neckRingEstrusIds = append(neckRingEstrusIds, neckRingEstrus.Id) } if len(neckRingEstrusIds) <= 0 { return nil } if err = s.DB.Transaction(func(tx *gorm.DB) error { for _, id := range neckRingEstrusIds { if err = tx.Model(new(model.NeckRingEstrus)). Where("id = ?", id). Updates(map[string]interface{}{ "check_result": pasturePb.CheckResult_Fail, "check_user_id": userModel.SystemUser.Id, "check_user_name": userModel.SystemUser.Name, "check_at": time.Now().Local().Unix(), "is_show": pasturePb.IsShow_No, }).Error; err != nil { return xerr.WithStack(err) } if err = tx.Model(new(model.NeckRingEstrusWarning)). Where("neck_ring_estrus_id = ?", id). Updates(map[string]interface{}{ "is_show": pasturePb.IsShow_No, }).Error; err != nil { return xerr.WithStack(err) } } return nil }); err != nil { return xerr.WithStack(err) } return nil } func (s *StoreEntry) NeckRingNoDiseaseBatch(ctx context.Context, req *pasturePb.NeckRingNoEstrusBatchRequest) error { userModel, err := s.GetUserModel(ctx) if err != nil { return xerr.WithStack(err) } if len(req.EarNumbers) <= 0 { return xerr.Custom("请选择牛号") } nowTime := time.Now().Local() startTime := nowTime.AddDate(0, 0, -1).Format(model.LayoutDate2) endTime := nowTime.AddDate(0, 0, 1).Format(model.LayoutDate2) startTimeUnix := util.TimeParseLocalUnix(startTime) endTimeUnix := util.TimeParseLocalUnix(endTime) startTime = time.Unix(startTimeUnix, 0).Local().Format(model.LayoutTime) endTime = time.Unix(endTimeUnix, 0).Local().Format(model.LayoutTime) neckRingHealthWarningList := make([]*model.NeckRingHealthWarning, 0) if err = s.DB.Model(new(model.NeckRingHealthWarning)). Where("pasture_id = ?", userModel.AppPasture.Id). Where("date_time BETWEEN ? AND ?", startTime, endTime). Where("ear_number IN ?", req.EarNumbers). Where("is_show = ?", pasturePb.IsShow_Ok). Find(&neckRingHealthWarningList).Error; err != nil { return xerr.WithStack(err) } if len(neckRingHealthWarningList) <= 0 { return nil } neckRingHealthIds := make([]int64, 0) for _, v := range neckRingHealthWarningList { neckRingHealth := &model.NeckRingHealth{} if err = s.DB.Model(new(model.NeckRingHealth)). Where("pasture_id = ?", userModel.AppPasture.Id). Where("id = ?", v.NeckRingHealthId). Where("is_show = ?", pasturePb.IsShow_Ok). First(neckRingHealth).Error; err != nil { zaplog.Error("NeckRingNoEstrusBatch", zap.Any("err", err), zap.Any("neckRingEstrusWarning", v)) return xerr.Customf("数据异常: %s", v.EarNumber) } neckRingHealthIds = append(neckRingHealthIds, neckRingHealth.Id) } if len(neckRingHealthIds) <= 0 { return nil } if err = s.DB.Transaction(func(tx *gorm.DB) error { for _, id := range neckRingHealthIds { if err = tx.Model(new(model.NeckRingHealth)). Where("id = ?", id). Updates(map[string]interface{}{ "check_result": pasturePb.CheckResult_Fail, "check_user_id": userModel.SystemUser.Id, "check_user_name": userModel.SystemUser.Name, "check_at": time.Now().Local().Unix(), "is_show": pasturePb.IsShow_No, }).Error; err != nil { return xerr.WithStack(err) } if err = tx.Model(new(model.NeckRingHealthWarning)). Where("neck_ring_health_id = ?", id). Updates(map[string]interface{}{ "is_show": pasturePb.IsShow_No, }).Error; err != nil { return xerr.WithStack(err) } } return nil }); err != nil { return xerr.WithStack(err) } return nil } func (s *StoreEntry) EstrusWarningQuery(ctx context.Context, pastureId int64) (*gorm.DB, error) { nowTime := time.Now().Local() startTime := time.Unix(util.TimeParseLocalUnix(nowTime.Format(model.LayoutDate2)), 0).Local().Format(model.LayoutTime) entTime := time.Unix(util.TimeParseLocalEndUnix(nowTime.AddDate(0, 0, 1).Local().Format(model.LayoutDate2)), 0).Format(model.LayoutTime) systemBasic, err := s.FindSystemBasic(ctx, pastureId, model.EstrusWaringDays) if err != nil { return nil, xerr.WithStack(err) } return s.DB.Table(fmt.Sprintf("%s as a", new(model.NeckRingEstrusWarning).TableName())). Joins(fmt.Sprintf("JOIN %s AS b on a.cow_id = b.id", new(model.Cow).TableName())). Where("b.last_mating_at < UNIX_TIMESTAMP(a.date_time)"). Where("b.admission_status = ?", pasturePb.AdmissionStatus_Admission). Where("b.is_forbidden_mating = ?", pasturePb.IsShow_No). Where("a.level >= ?", pasturePb.EstrusLevel_Low). Where("a.pasture_id = ?", pastureId). Where("a.date_time BETWEEN ? AND ?", startTime, entTime). Where(s.DB.Where("b.last_mating_at < UNIX_TIMESTAMP(a.first_time)"). Or(s.DB.Where("b.last_mating_at = ?", 0). Where("b.calving_age > ?", systemBasic.MinValue). Or("b.lact = ?", 0))). Where("a.is_show = ?", pasturePb.IsShow_Ok), nil } func (s *StoreEntry) AbortionWarningQuery(ctx context.Context, pastureId int64) (*gorm.DB, error) { return s.DB.Table(fmt.Sprintf("%s as a", new(model.NeckRingEstrusWarning).TableName())). Joins(fmt.Sprintf("JOIN %s AS b on a.cow_id = b.id", new(model.Cow).TableName())). Where("b.pregnancy_age BETWEEN ? AND ?", 1, 260). Where("b.admission_status = ?", pasturePb.AdmissionStatus_Admission). Where("b.is_pregnant = ?", pasturePb.IsShow_Ok). Where("a.level >= ?", pasturePb.EstrusLevel_Middle). Where("a.pasture_id = ?", pastureId). Where("a.is_show = ?", pasturePb.IsShow_Ok), nil }