package backend import ( "context" "fmt" "kpt-pasture/model" "net/http" "strconv" "strings" "time" pasturePb "gitee.com/xuyiping_admin/go_proto/proto/go/backend/cow" "gitee.com/xuyiping_admin/pkg/xerr" "gorm.io/gorm" ) func (s *StoreEntry) ParseCowIds(ctx context.Context, pastureId int64, cowIds string) ([]*model.Cow, error) { if len(cowIds) == 0 { return nil, xerr.Custom("cow id is required") } cowIdStr := strings.Split(cowIds, ",") var cowIdInts = make([]int64, 0) for _, v := range cowIdStr { cowId, err := strconv.ParseInt(v, 10, 64) if err != nil { return nil, xerr.Customf("错误的牛号: %s", v) } cowIdInts = append(cowIdInts, cowId) } cowList, err := s.GetCowInfoByCowIds(ctx, pastureId, cowIdInts) if err != nil { return nil, xerr.WithStack(err) } return cowList, nil } func (s *StoreEntry) EnterList(ctx context.Context, req *pasturePb.SearchEventRequest, pagination *pasturePb.PaginationModel) (*pasturePb.SearchEnterEventResponse, error) { userModel, err := s.GetUserModel(ctx) if err != nil { return nil, xerr.WithStack(err) } eventEnterList := make([]*model.EventEnter, 0) var count int64 = 0 pref := s.DB.Model(new(model.EventEnter)). Where("pasture_id = ?", userModel.AppPasture.Id) if len(req.CowId) > 0 { cowIds := strings.Split(req.CowId, ",") pref.Where("cow_id IN ?", cowIds) } if req.EarNumber != "" { pref.Where("ear_number = ?", req.EarNumber) } if req.StartDayAt > 0 && req.EndDayAt > 0 && req.EndDayAt >= req.StartDayAt { pref.Where("enter_at BETWEEN ? AND ?", req.StartDayAt, req.EndDayAt) } if err = pref.Order("id desc"). Count(&count).Limit(int(pagination.PageSize)). Offset(int(pagination.PageOffset)). Find(&eventEnterList).Error; err != nil { return nil, xerr.WithStack(err) } penMap := s.PenMap(ctx, userModel.AppPasture.Id) breedStatusMap := s.CowBreedStatusMap() cowSourceMap := s.CowSourceMap() cowTypeMap := s.CowTypeMap() cowKindMap := s.CowKindMap() return &pasturePb.SearchEnterEventResponse{ Code: http.StatusOK, Msg: "ok", Data: &pasturePb.SearchEnterEventData{ List: model.EventEnterSlice(eventEnterList).ToPB(penMap, breedStatusMap, cowSourceMap, cowTypeMap, cowKindMap), Total: int32(count), PageSize: pagination.PageSize, Page: pagination.Page, }, }, nil } func (s *StoreEntry) CreateEnter(ctx context.Context, req *pasturePb.EventEnterRequest) (err error) { userModel, err := s.GetUserModel(ctx) if err != nil { return xerr.WithStack(err) } if err = s.EnterCheck(ctx, req); err != nil { return xerr.WithStack(err) } req.MessengerId = int32(userModel.SystemUser.Id) req.MessengerName = userModel.SystemUser.Name if req.OperationId > 0 { systemUser, _ := s.GetSystemUserById(ctx, int64(req.OperationId)) req.OperationName = systemUser.Name } penMap := s.PenMap(ctx, userModel.AppPasture.Id) if len(penMap) <= 0 { return xerr.Customf("请先设置牛舍信息") } newCow := model.NewEnterCow(userModel.AppPasture.Id, req, penMap) if err = s.DB.Transaction(func(tx *gorm.DB) error { if err = tx.Create(newCow).Error; err != nil { return xerr.WithStack(err) } newEventEnter := model.NewEventEnter(userModel.AppPasture.Id, newCow.Id, req) if err = tx.Create(newEventEnter).Error; err != nil { return xerr.WithStack(err) } eventWeight := model.NewEventWeight( userModel.AppPasture.Id, newCow, userModel.SystemUser, &pasturePb.EventWeight{ WeightAt: req.EnterAt, Remarks: "入场体重", OperationId: req.OperationId, OperationName: req.OperationName, Weight: req.Weight, }) if err = tx.Create(eventWeight).Error; err != nil { return xerr.WithStack(err) } cowLogs := s.SubmitEventLog(ctx, userModel.AppPasture.Id, newCow, pasturePb.EventType_Enter, 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) GroupTransferList(ctx context.Context, req *pasturePb.SearchEventRequest, pagination *pasturePb.PaginationModel) (*pasturePb.SearchTransferGroupEventResponse, error) { userModel, err := s.GetUserModel(ctx) if err != nil { return nil, xerr.WithStack(err) } eventGroupTransferList := make([]*pasturePb.EventTransferGroupData, 0) var count int64 = 0 pref := s.DB.Table(fmt.Sprintf("%s as a", new(model.EventTransferGroup).TableName())). Select(`a.id,a.cow_id,a.pen_in_id as transfer_in_pen_id,a.pen_out_id as transfer_out_pen_id,a.lact,a.remarks, a.transfer_reason_id,a.transfer_reason_name,a.transfer_date,a.created_at,a.operation_id,a.operation_name, b.name as transfer_in_pen_name,c.name as transfer_out_pen_name,f.lact,f.ear_number`). Joins(fmt.Sprintf("JOIN %s AS b ON a.pen_in_id = b.id", new(model.Pen).TableName())). Joins(fmt.Sprintf("JOIN %s AS c on a.pen_out_id = c.id", new(model.Pen).TableName())). Joins(fmt.Sprintf("JOIN %s AS f ON a.cow_id = f.id", new(model.Cow).TableName())). Where("a.pasture_id = ?", userModel.AppPasture.Id) if req.EarNumber != "" { pref.Where("a.ear_number = ?", req.EarNumber) } if req.TransferReasonId > 0 { pref.Where("a.transfer_reason_id = ?", req.TransferReasonId) } if req.TransferInPenId > 0 { pref.Where("a.pen_in_id = ?", req.TransferInPenId) } if req.StartDayAt > 0 && req.EndDayAt > 0 && req.EndDayAt >= req.StartDayAt { pref.Where("a.transfer_date BETWEEN ? AND ?", time.Unix(int64(req.StartDayAt), 0).Format(model.LayoutDate2), time.Unix(int64(req.EndDayAt), 0).Format(model.LayoutDate2)) } if err = pref.Order("a.id desc").Group("a.id"). Count(&count).Limit(int(pagination.PageSize)). Offset(int(pagination.PageOffset)). Find(&eventGroupTransferList).Error; err != nil { return nil, xerr.WithStack(err) } return &pasturePb.SearchTransferGroupEventResponse{ Code: http.StatusOK, Msg: "ok", Data: &pasturePb.SearchTransferGroupEventData{ List: eventGroupTransferList, Total: int32(count), PageSize: pagination.PageSize, Page: pagination.Page, }, }, nil } func (s *StoreEntry) CreateGroupTransfer(ctx context.Context, req *pasturePb.TransferGroupEventRequest) (err error) { userModel, err := s.GetUserModel(ctx) if err != nil { return xerr.WithStack(err) } if len(req.Body) <= 0 { return xerr.Custom("请选择牛只数据") } if len(req.Body) > 50 { return xerr.Custom("一次最多只能转移50头牛") } transferReasonMap := s.GroupTransferReasonMap() penMap := s.PenMap(ctx, userModel.AppPasture.Id) if err = s.DB.Transaction(func(tx *gorm.DB) error { for _, v := range req.Body { cow, err := s.GetCowInfoByEarNumber(ctx, userModel.AppPasture.Id, v.EarNumber) if err != nil { return xerr.WithStack(err) } // 转去栏舍和当前栏舍相同,则不处理 if cow.PenId == v.TransferInPenId { return xerr.Custom("转入栏舍和牛只当前栏舍不能一致") } operationUser, err := s.GetSystemUserById(ctx, int64(v.OperationId)) if err != nil { return xerr.WithStack(err) } newEventTransferGroup := model.NewEventTransferGroup(userModel.AppPasture.Id, cow, v, transferReasonMap, userModel.SystemUser, operationUser) if err = tx.Model(new(model.EventTransferGroup)).Create(newEventTransferGroup).Error; err != nil { return xerr.WithStack(err) } if err = s.DB.Model(cow). Updates(map[string]interface{}{ "pen_id": v.TransferInPenId, "pen_name": penMap[v.TransferReasonId].Name, }).Error; err != nil { return xerr.WithStack(err) } // 事件日志 cowLogs := s.SubmitEventLog(ctx, userModel.AppPasture.Id, cow, pasturePb.EventType_Transfer_Ben, newEventTransferGroup) 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) BodyScoreList(ctx context.Context, req *pasturePb.SearchEventRequest, pagination *pasturePb.PaginationModel) (*pasturePb.SearchBodyScoreEventResponse, error) { userModel, err := s.GetUserModel(ctx) if err != nil { return nil, xerr.WithStack(err) } bodyScoreList := make([]*pasturePb.BodyScoreList, 0) var count int64 = 0 pref := s.DB.Model(new(model.EventBodyScore)). Select("*,score as body_score"). Where("pasture_id = ?", userModel.AppPasture.Id) if len(req.CowId) > 0 { cowIds := strings.Split(req.CowId, ",") pref.Where("cow_id IN ?", cowIds) } if req.EarNumber != "" { pref.Where("ear_number = ?", req.EarNumber) } if err = pref.Order("id desc"). Count(&count).Limit(int(pagination.PageSize)). Offset(int(pagination.PageOffset)). Find(&bodyScoreList).Error; err != nil { return nil, xerr.WithStack(err) } return &pasturePb.SearchBodyScoreEventResponse{ Code: http.StatusOK, Msg: "ok", Data: &pasturePb.SearchBodyScoreData{ List: bodyScoreList, Total: int32(count), PageSize: pagination.PageSize, Page: pagination.Page, }, }, nil } func (s *StoreEntry) CreateBodyScore(ctx context.Context, req *pasturePb.BodyScoreEventRequest) error { if req.CowId <= 0 { return xerr.Custom("请选择相关牛只") } 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 cowInfo, err := s.GetCowInfoByCowId(ctx, userModel.AppPasture.Id, int64(req.CowId)) if err != nil { return xerr.WithStack(err) } bodyScourEvent := model.NewEventBodyScore(cowInfo, userModel.AppPasture.Id, userModel.SystemUser, req) return s.DB.Model(new(model.EventBodyScore)).Create(bodyScourEvent).Error } func (s *StoreEntry) WeightList(ctx context.Context, req *pasturePb.SearchEventRequest, pagination *pasturePb.PaginationModel) (*pasturePb.SearchWeightEventResponse, error) { userModel, err := s.GetUserModel(ctx) if err != nil { return nil, xerr.WithStack(err) } weightList := make([]*pasturePb.SearchWeightList, 0) var count int64 = 0 pref := s.DB.Table(fmt.Sprintf("%s as a", new(model.EventWeight).TableName())). Select(`a.id,a.cow_id,a.ear_number,ROUND(a.weight/1000, 2) as weight,a.height,a.lact,a.day_age,a.weight_at,a.remarks,a.created_at, a.updated_at,a.message_id,a.operation_id,a.message_name,a.operation_name`). Where("a.pasture_id = ?", userModel.AppPasture.Id) 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 req.StartDayAt > 0 && req.EndDayAt > 0 && req.EndDayAt >= req.StartDayAt { pref.Where("a.weight_at BETWEEN ? AND ?", req.StartDayAt, req.EndDayAt) } if err = pref.Order("a.id desc"). Count(&count).Limit(int(pagination.PageSize)). Offset(int(pagination.PageOffset)). Find(&weightList).Error; err != nil { return nil, xerr.WithStack(err) } return &pasturePb.SearchWeightEventResponse{ Code: http.StatusOK, Msg: "ok", Data: &pasturePb.SearchWeightData{ List: weightList, Total: int32(count), PageSize: pagination.PageSize, Page: pagination.Page, }, }, nil } func (s *StoreEntry) WeightBatch(ctx context.Context, req *pasturePb.BatchEventWeight) (err error) { userModel, err := s.GetUserModel(ctx) if err != nil { return xerr.WithStack(err) } if len(req.Items) <= 0 { return xerr.Custom("称重数据不能为空") } if len(req.Items) > 50 { return xerr.Custom("一次最多只能转移50头牛") } if err = s.DB.Transaction(func(tx *gorm.DB) error { for _, item := range req.Items { cow, err := s.GetCowInfoByEarNumber(ctx, userModel.AppPasture.Id, item.EarNumber) if err != nil { return xerr.WithStack(err) } // 更新牛只信息 cow.EventWeightUpdate(int64(item.Weight*1000), int64(item.WeightAt)) if err = tx.Model(new(model.Cow)). Select("last_second_weight_at", "last_second_weight", "last_weight_at", "current_weight"). Where("id = ?", cow.Id). Where("admission_status = ?", pasturePb.AdmissionStatus_Admission). Updates(cow).Error; err != nil { return xerr.WithStack(err) } operationUser, _ := s.GetSystemUserById(ctx, int64(item.OperationId)) item.OperationName = operationUser.Name // 创建牛只的体重记录 eventWeight := model.NewEventWeight(userModel.AppPasture.Id, cow, userModel.SystemUser, item) if err = tx.Create(eventWeight).Error; err != nil { return xerr.WithStack(err) } cowLogs := s.SubmitEventLog(ctx, userModel.AppPasture.Id, cow, pasturePb.EventType_Weight, item) 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 }