package backend import ( "context" "fmt" "kpt-pasture/model" "net/http" "strings" "time" "gitee.com/xuyiping_admin/pkg/logger/zaplog" "go.uber.org/zap" pasturePb "gitee.com/xuyiping_admin/go_proto/proto/go/backend/cow" "gitee.com/xuyiping_admin/pkg/xerr" "gorm.io/gorm" ) func (s *StoreEntry) CalvingList(ctx context.Context, req *pasturePb.SearchEventRequest, pagination *pasturePb.PaginationModel) (*pasturePb.SearchLavingEventResponse, error) { userModel, err := s.GetUserModel(ctx) if err != nil { return nil, xerr.WithStack(err) } lavingList := make([]*model.EventCalvingList, 0) var count int64 = 0 pref := s.DB.Table(fmt.Sprintf("%s as a", new(model.EventCalving).TableName())). Select(`a.*,b.name as pen_name,c.name as staff_member_name`). Joins(fmt.Sprintf("JOIN %s AS b on a.pen_id = b.id", new(model.Pen).TableName())). Joins(fmt.Sprintf("JOIN %s AS c on a.operation_id = c.id", new(model.SystemUser).TableName())). Where("a.pasture_id = ?", userModel.AppPasture.Id).Where("a.status = ?", pasturePb.IsShow_No) if len(req.CowId) > 0 { cowIds := strings.Split(req.CowId, ",") pref.Where("a.cow_id IN ?", cowIds) } if req.EarNumber != "" { pref.Where("a.ear_number = ?", req.EarNumber) } if err = pref.Order("a.id desc"). Count(&count).Limit(int(pagination.PageSize)). Offset(int(pagination.PageOffset)). Find(&lavingList).Error; err != nil { return nil, xerr.WithStack(err) } calvingIds := make([]int64, 0) for _, v := range lavingList { calvingIds = append(calvingIds, v.Id) } calvingCalfList := make([]*model.CalvingCalf, 0) if err = s.DB.Model(new(model.CalvingCalf)). Where("calving_id IN ?", calvingIds). Find(&calvingCalfList).Error; err != nil { return nil, xerr.WithStack(err) } return &pasturePb.SearchLavingEventResponse{ Code: http.StatusOK, Msg: "ok", Data: &pasturePb.SearchLavingData{ List: model.EventCalvingListSlice(lavingList).ToPB(calvingCalfList), Total: int32(count), PageSize: pagination.PageSize, Page: pagination.Page, }, }, nil } func (s *StoreEntry) CalvingCreate(ctx context.Context, req *pasturePb.EventCalving) (err error) { userModel, err := s.GetUserModel(ctx) if err != nil { return xerr.WithStack(err) } cow, err := s.GetCowInfoByEarNumber(ctx, userModel.AppPasture.Id, req.EarNumber) if err != nil { zaplog.Error("CalvingCreate", zap.Any("cow_id", req.CowId), zap.Any("err", err)) return xerr.Custom("请选择相关牛只") } if len(req.CalfItemList) != int(req.ChildNumber) { return xerr.Custom("犊牛信息与产子数不相符") } if cow.IsPregnant != pasturePb.IsShow_Ok || cow.BreedStatus != pasturePb.BreedStatus_Pregnant { return xerr.Custom("该母牛未配种") } operationUser, err := s.GetSystemUserById(ctx, int64(req.OperationId)) if err != nil { return xerr.Customf("获取操作人员信息失败: %s", err.Error()) } req.OperationName = operationUser.Name penMap := s.PenMap(ctx, userModel.AppPasture.Id) newEventCalving := &model.EventCalving{} if err = s.DB.Model(new(model.EventCalving)). Where("cow_id = ?", cow.Id). Where("lact = ?", cow.Lact). Where("status = ?", pasturePb.IsShow_No). First(newEventCalving).Error; err != nil { return xerr.Custom("该母牛信息不存在") } if err = s.DB.Transaction(func(tx *gorm.DB) error { // 更新产犊事件表 newEventCalving.EventUpdate(operationUser, userModel.SystemUser, req, cow) if err = tx.Model(new(model.EventCalving)). Select("operation_id", "operation_name", "message_id", "message_name", "reality_day", "day_age", "pregnancy_age", "bull_number", "calving_level", "child_number", "status", "is_inducing_childbirth", "pen_id", "dystocia_reason", "remarks"). Where("id = ?", newEventCalving.Id). Updates(newEventCalving).Error; err != nil { return xerr.WithStack(err) } for _, calf := range req.CalfItemList { // 犊牛信息 newCalvingCalf := model.NewEventCalvingCalf(userModel.AppPasture.Id, newEventCalving.Id, int64(req.CalvingAt), cow, penMap, calf) if err = tx.Create(newCalvingCalf).Error; err != nil { return xerr.WithStack(err) } if calf.IsLive == pasturePb.IsShow_No || calf.IsAdoption == pasturePb.IsShow_No { continue } newCalfCow := model.NewCalfCow(cow, newCalvingCalf) if err = tx.Create(newCalfCow).Error; err != nil { return xerr.WithStack(err) } if err = tx.Model(new(model.CalvingCalf)).Where("id = ?", newCalvingCalf.Id).Update("cow_id", newCalfCow.Id).Error; err != nil { return xerr.WithStack(err) } // 犊牛日志 cowLogs := s.SubmitEventLog(ctx, userModel.AppPasture.Id, newCalfCow, pasturePb.EventType_Birth, calf) if err = tx.Table(cowLogs.TableName()).Create(cowLogs).Error; err != nil { return xerr.WithStack(err) } } // 更新母牛信息 cow.EventCalvingUpdate(int64(req.CalvingAt)) if err = tx.Model(cow). Select("calving_age", "mating_times", "pregnancy_age", "lact", "breed_status", "is_pregnant", "last_calving_at"). Where("id = ?", cow.Id). Updates(cow).Error; err != nil { return xerr.WithStack(err) } // 母牛事件日志 cowLogs := s.SubmitEventLog(ctx, userModel.AppPasture.Id, cow, pasturePb.EventType_Calving, req) if err = tx.Table(cowLogs.TableName()).Create(cowLogs).Error; err != nil { return xerr.WithStack(err) } return nil }); err != nil { return xerr.WithStack(err) } return nil } func (s *StoreEntry) SameTimeCreate(ctx context.Context, req *pasturePb.EventSameTime) (err error) { userModel, err := s.GetUserModel(ctx) if err != nil { return xerr.WithStack(err) } operationUser, err := s.GetSystemUserById(ctx, int64(req.OperationId)) if err != nil { return xerr.WithStack(err) } req.OperationName = operationUser.Name eventCowSameTime, err := s.GetEventCowSameTimeByCowId(ctx, userModel.AppPasture.Id, int64(req.CowId)) if err != nil { zaplog.Error("SameTimeCreate", zap.Any("err", err), zap.Any("req", req)) return xerr.Customf("异常数据") } drugs := &model.Drugs{} if drugs, err = s.GetDrugsById(ctx, userModel.AppPasture.Id, int64(req.DrugsId)); err != nil { zaplog.Error("SameTimeCreate", zap.Any("err", err), zap.Any("req", req)) return xerr.Customf("该药品不存在: %d", req.DrugsId) } req.DrugsName = drugs.Name eventCowSameTime.EventUpdate(drugs, req.Usage, req.Remarks, operationUser, userModel.SystemUser) if err = s.DB.Transaction(func(tx *gorm.DB) error { if err = tx.Model(new(model.EventCowSameTime)). Select("status", "drugs_id", "unit", "usage", "remarks", "operation_id", "operation_name"). Where("id = ?", eventCowSameTime.Id). Updates(eventCowSameTime).Error; err != nil { return xerr.WithStack(err) } // 记录牛只事件日志 cow, _ := s.GetCowInfoByCowId(ctx, userModel.AppPasture.Id, eventCowSameTime.CowId) cowLogs := s.SubmitEventLog(ctx, userModel.AppPasture.Id, cow, pasturePb.EventType_Seme_Time, req) if err = s.DB.Table(cowLogs.TableName()).Create(cowLogs).Error; err != nil { return xerr.WithStack(err) } return nil }); err != nil { } return nil } func (s *StoreEntry) SameTimeBatch(ctx context.Context, req *pasturePb.EventSameTimeBatch) (err error) { userModel, err := s.GetUserModel(ctx) if err != nil { return xerr.WithStack(err) } operationUser, err := s.GetSystemUserById(ctx, int64(req.OperationId)) if err != nil { return xerr.Customf("异常数据") } req.OperationName = operationUser.Name drugs := &model.Drugs{} if drugs, err = s.GetDrugsById(ctx, userModel.AppPasture.Id, int64(req.DrugsId)); err != nil { zaplog.Error("SameTimeBatch", zap.Any("err", err), zap.Any("req", req)) return xerr.Customf("该药物不存在: %d", req.DrugsId) } req.DrugsName = drugs.Name nowTime := time.Now().Format(model.LayoutDate2) eventCowSameTimeList := make([]*model.EventCowSameTime, 0) for _, v := range req.CowIds { eventCowSameTime, err := s.GetEventCowSameTimeByCowId(ctx, userModel.AppPasture.Id, int64(v)) if err != nil { zaplog.Error("SameTimeCreate", zap.Any("err", err), zap.Any("req", req)) return xerr.WithStack(err) } if time.Unix(eventCowSameTime.PlanDay, 0).Format(model.LayoutDate2) != nowTime { return xerr.Customf("该牛只不是今日计划: %d", eventCowSameTime.EarNumber) } eventCowSameTimeList = append(eventCowSameTimeList, eventCowSameTime) } if err = s.DB.Transaction(func(tx *gorm.DB) error { for _, v := range eventCowSameTimeList { // 更新SameTime v.EventUpdate(drugs, req.Usage, req.Remarks, userModel.SystemUser, operationUser) if err = tx.Model(new(model.EventCowSameTime)). Select("status", "drugs_id", "unit", "usage", "remarks", "operation_id", "operation_name"). Where("id = ?", v.Id). Updates(v).Error; err != nil { return xerr.WithStack(err) } cow, _ := s.GetCowInfoByCowId(ctx, userModel.AppPasture.Id, v.CowId) logItem := &pasturePb.EventSameTime{ Id: int32(v.Id), CowId: int32(v.CowId), SameTimeId: int32(v.SameTimeId), SameTimeType: v.SameTimeType, SameTimeTypeName: v.SameTimeName, DrugsId: int32(v.DrugsId), DrugsName: drugs.Name, Usage: req.Usage, OperationId: int32(operationUser.Id), OperationName: operationUser.Name, SameTimeAt: req.SameTimeAt, } cowLogs := s.SubmitEventLog(ctx, userModel.AppPasture.Id, cow, pasturePb.EventType_Seme_Time, logItem) if err = tx.Table(cowLogs.TableName()).Create(cowLogs).Error; err != nil { return xerr.WithStack(err) } } return nil }); err != nil { return xerr.WithStack(err) } return nil } func (s *StoreEntry) SameTimeList( ctx context.Context, req *pasturePb.SearchEventRequest, pagination *pasturePb.PaginationModel, ) (*pasturePb.SearchSameTimeResponse, error) { userModel, err := s.GetUserModel(ctx) if err != nil { return nil, xerr.WithStack(err) } cowSameTimeList := make([]*model.EventCowSameTime, 0) var count int64 = 0 pref := s.DB.Table(new(model.EventCowSameTime).TableName()).Where("pasture_id = ?", userModel.AppPasture.Id) if req.CowId != "" { cowIds := strings.Split(req.CowId, ",") pref.Where("cow_id IN ?", cowIds) } if req.EarNumber != "" { pref.Where("ear_number = ?", req.EarNumber) } if err = pref.Count(&count). Limit(int(pagination.PageSize)). Offset(int(pagination.PageOffset)). Find(&cowSameTimeList).Error; err != nil { return nil, xerr.WithStack(err) } sameTimeTypeMap := s.SameTimeTypeMap() return &pasturePb.SearchSameTimeResponse{ Code: http.StatusOK, Msg: "ok", Data: &pasturePb.SameTimeData{ List: model.EventCowSameTimeSlice(cowSameTimeList).ToPB(sameTimeTypeMap), Total: int32(count), PageSize: pagination.PageSize, Page: pagination.Page, }, }, nil } func (s *StoreEntry) EstrusList(ctx context.Context, req *pasturePb.SearchEventRequest, pagination *pasturePb.PaginationModel) (*pasturePb.SearchEventEstrusResponse, error) { userModel, err := s.GetUserModel(ctx) if err != nil { return nil, xerr.WithStack(err) } estrusList := make([]*model.EventEstrus, 0) var count int64 = 0 pref := s.DB.Table(new(model.EventEstrus).TableName()). Where("is_show = ?", pasturePb.IsShow_Ok). Where("pasture_id = ?", userModel.AppPasture.Id). Where("expose_estrus_type = ?", pasturePb.ExposeEstrusType_Natural_Estrus) if req.EarNumber != "" { pref.Where("ear_number = ?", req.EarNumber) } if req.StartDayAt > 0 && req.EndDayAt > 0 && req.StartDayAt <= req.EndDayAt { pref.Where("reality_day BETWEEN ? AND ?", req.StartDayAt, req.EndDayAt) } if err = pref.Order("id desc"). Count(&count).Limit(int(pagination.PageSize)). Offset(int(pagination.PageOffset)). Find(&estrusList).Error; err != nil { return nil, xerr.WithStack(err) } return &pasturePb.SearchEventEstrusResponse{ Code: http.StatusOK, Msg: "ok", Data: &pasturePb.SearchEventEstrusData{ List: model.EventEstrusSlice(estrusList).ToPB(), Total: int32(count), PageSize: pagination.PageSize, Page: pagination.Page, }, }, nil } func (s *StoreEntry) EstrusBatchMating(ctx context.Context, req *pasturePb.EventNaturalEstrusBatch) (err error) { userModel, err := s.GetUserModel(ctx) if err != nil { return xerr.WithStack(err) } eventEstrusList, eventMatingList, err := s.EstrusCheckDataCheck(ctx, userModel, req.Items) if err != nil { return xerr.WithStack(err) } if err = s.DB.Transaction(func(tx *gorm.DB) error { if len(eventMatingList) > 0 { if err = tx.Model(new(model.EventMating)).Create(eventMatingList).Error; err != nil { return xerr.WithStack(err) } } if len(eventEstrusList) > 0 { if err = tx.Model(new(model.EventEstrus)).Create(eventEstrusList).Error; err != nil { return xerr.WithStack(err) } } // 记录事件日志 for _, v := range eventEstrusList { cow, _ := s.GetCowInfoByCowId(ctx, userModel.AppPasture.Id, v.CowId) // 更新牛最近发情时间 cow.EstrusUpdate(v.RealityDay) if err = tx.Model(cow). Select("last_estrus_at"). Where("id = ?", cow.Id). Updates(cow).Error; err != nil { return xerr.WithStack(err) } cowLogs := s.SubmitEventLog(ctx, userModel.AppPasture.Id, cow, pasturePb.EventType_Estrus, v) if err = tx.Table(cowLogs.TableName()).Create(cowLogs).Error; err != nil { return xerr.WithStack(err) } } return nil }); err != nil { return xerr.WithStack(err) } return nil }