package backend import ( "context" "kpt-pasture/model" "net/http" "strings" pasturePb "gitee.com/xuyiping_admin/go_proto/proto/go/backend/cow" "gitee.com/xuyiping_admin/pkg/logger/zaplog" "gitee.com/xuyiping_admin/pkg/xerr" "go.uber.org/zap" "gorm.io/gorm" ) func (s *StoreEntry) DeathBatch(ctx context.Context, req *pasturePb.EventDeathBatch) (err error) { userModel, err := s.GetUserModel(ctx) if err != nil { return xerr.WithStack(err) } if len(req.Items) <= 0 { return xerr.Custom("请选择相关牛只") } newEventDeathList := make([]*model.EventDeathModel, 0) for _, item := range req.Items { cow, err := s.GetCowInfoByEarNumber(ctx, userModel.AppPasture.Id, item.EarNumber) if err != nil { zaplog.Error("DeathBatch", zap.Any("item", item), zap.Any("err", err)) return xerr.Customf("获取牛只信息失败: %s", item.EarNumber) } if name, ok := s.DeadReasonMap()[item.DeathReasonKind]; ok { item.DeathReasonName = name } operationUser, err := s.GetSystemUserById(ctx, int64(item.OperationId)) if err != nil { zaplog.Error("DeathBatch", zap.Any("item", item), zap.Any("err", err)) return xerr.Customf("获取操作人员信息失败: %d", item.OperationId) } if name, ok := s.CowDeathDestinationMap()[item.DeathDestinationKind]; ok { item.DeathDestinationName = name } newEventDeath := model.NewEventDeath(userModel.AppPasture.Id, cow, item, userModel.SystemUser, operationUser) eventDeathModel := &model.EventDeathModel{ Cow: cow, EventDeath: newEventDeath, NeckRing: nil, } if neckRing, ok := s.NeckRingIsExist(userModel.AppPasture.Id, item.EarNumber); ok && neckRing != nil { eventDeathModel.NeckRing = neckRing } newEventDeathList = append(newEventDeathList, eventDeathModel) } if err = s.DB.Transaction(func(tx *gorm.DB) error { // 记录事件日志 for _, item := range newEventDeathList { if err = tx.Create(item.EventDeath).Error; err != nil { return xerr.WithStack(err) } // 更新牛只死亡状态 item.Cow.EventDeathUpdate(item.Cow.DepartureAt) if err = tx.Model(new(model.Cow)). Select("admission_status", "health_status", "departure_at"). Where("id = ?", item.Cow.Id). Updates(item.Cow).Error; err != nil { return xerr.WithStack(err) } // 解绑脖环 if item.NeckRing != nil { item.NeckRing.EventUnBindUpdate() if err = tx.Model(new(model.NeckRing)). Select("is_bind", "cow_id", "ear_number", "wear_at", "error_reason", "operation_id", "operation_name"). Where("id = ?", item.NeckRing.Id). Updates(item.NeckRing).Error; err != nil { return xerr.WithStack(err) } newNeckRingBindLog := model.NewNeckRingBindLog(userModel.AppPasture.Id, item.NeckRing.NeckRingNumber, item.Cow, userModel.SystemUser, "死亡解绑") if err = tx.Model(new(model.NeckRingBindLog)).Create(newNeckRingBindLog).Error; err != nil { return xerr.WithStack(err) } } // 记录事件日志 cowLogs := s.SubmitEventLog(ctx, userModel.AppPasture.Id, item.Cow, pasturePb.EventType_Death, item.EventDeath) 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) DeathList(ctx context.Context, req *pasturePb.SearchEventRequest, pagination *pasturePb.PaginationModel) (*pasturePb.EventDeathResponse, error) { userModel, err := s.GetUserModel(ctx) if err != nil { return nil, xerr.WithStack(err) } eventDeathList := make([]*model.EventDeath, 0) pref := s.DB.Model(new(model.EventDeath)). Where("pasture_id = ?", userModel.AppPasture.Id) if req.StartDayAt > 0 && req.EndDayAt > 0 && req.EndDayAt >= req.StartDayAt { pref.Where("death_at BETWEEN ? AND ?", req.StartDayAt, req.EndDayAt) } if req.EarNumber != "" { pref.Where("ear_number = ?", req.EarNumber) } var count int64 if err = pref.Order("id desc"). Count(&count).Limit(int(pagination.PageSize)). Offset(int(pagination.PageOffset)). Find(&eventDeathList).Error; err != nil { return nil, xerr.WithStack(err) } return &pasturePb.EventDeathResponse{ Code: http.StatusOK, Msg: "ok", Data: &pasturePb.EventDeathData{ List: model.EventDeathSlice(eventDeathList).ToPB(), Total: int32(count), PageSize: pagination.PageSize, Page: pagination.Page, }, }, nil } func (s *StoreEntry) CowEarNumberUpdate(ctx context.Context, req *pasturePb.EventReplaceEarNumber) (err error) { userModel, err := s.GetUserModel(ctx) if err != nil { return xerr.WithStack(err) } cow, err := s.GetCowInfoByCowId(ctx, userModel.AppPasture.Id, int64(req.CowId)) if err != nil { return xerr.Custom("未找到该牛只信息") } cow.EventEarNumberUpdate(req.EarNumber) if err = s.DB.Model(cow). Select("ear_number", "ear_old_number"). Where("id = ?", cow.Id). Updates(cow).Error; err != nil { return xerr.WithStack(err) } return nil } func (s *StoreEntry) CowSaleCreate(ctx context.Context, req *pasturePb.EventCowSale) error { userModel, err := s.GetUserModel(ctx) if err != nil { return xerr.WithStack(err) } cowList, err := s.GetCowInfoByEarNumbers(ctx, userModel.AppPasture.Id, req.EarNumbers) if err != nil { return xerr.WithStack(err) } if len(cowList) != len(req.EarNumbers) { return xerr.Custom("数据异常") } if len(cowList) <= 0 { return nil } dealerInfo := &model.SaleDealer{} if err = s.DB.Model(new(model.SaleDealer)). Where("id = ?", req.DealerId). First(dealerInfo).Error; err != nil { return xerr.Custom("经销商数据异常") } req.DealerName = dealerInfo.Name operationUser, err := s.GetSystemUserById(ctx, int64(req.OperationId)) if err != nil { return xerr.Custom("获取操作人员信息失败") } req.OperationName = operationUser.Name if req.SalesType == pasturePb.SalesType_Sales { req.OutReasonsKind = pasturePb.OutReasons_Invalid } if req.SalesType == pasturePb.SalesType_Out { if name, ok := s.CowOutReasonsMap()[req.OutReasonsKind]; ok { req.OutReasonsName = name } } newEventSale := model.NewEventSale(userModel.AppPasture.Id, dealerInfo, req, operationUser, userModel.SystemUser) eventCowLogList := make([]*model.EventCowLog, 0) neckRingList := make([]*model.NeckRing, 0) for _, cow := range cowList { var newEventCowLog *model.EventCowLog if req.SalesType == pasturePb.SalesType_Sales { newEventCowLog = s.SubmitEventLog(ctx, userModel.AppPasture.Id, cow, pasturePb.EventType_Sale, req) } if req.SalesType == pasturePb.SalesType_Out { newEventCowLog = s.SubmitEventLog(ctx, userModel.AppPasture.Id, cow, pasturePb.EventType_Out, req) } eventCowLogList = append(eventCowLogList, newEventCowLog) if cow.NeckRingNumber != "" { if neckRing, ok := s.NeckRingIsExist(userModel.AppPasture.Id, cow.NeckRingNumber); ok && neckRing != nil { neckRingList = append(neckRingList, neckRing) } } } eventSaleModel := &model.EventSaleModel{ CowList: cowList, SalesType: req.SalesType, EventSale: newEventSale, EventSaleCarList: model.NewEventSaleCarList(userModel.AppPasture.Id, newEventSale.Id, newEventSale.SaleAt, req.SaleVehicleItems), EventSaleCowList: model.NewEventSaleCowList(userModel.AppPasture.Id, newEventSale.Id, cowList), NeckRingList: neckRingList, EventCowLog: eventCowLogList, SaleAt: int64(req.SaleAt), } if err = s.DB.Transaction(func(tx *gorm.DB) error { // 创建销售数据 if err = tx.Model(new(model.EventSale)). Create(eventSaleModel.EventSale).Error; err != nil { return xerr.WithStack(err) } if len(eventSaleModel.EventSaleCarList) > 0 { if err = tx.Model(new(model.EventSaleCar)). Create(&eventSaleModel.EventSaleCarList).Error; err != nil { return xerr.WithStack(err) } } // 新增销售牛只数据 if len(eventSaleModel.EventSaleCowList) > 0 { if err = tx.Model(new(model.EventSaleCow)). Create(&eventSaleModel.EventSaleCowList).Error; err != nil { return xerr.WithStack(err) } } if len(eventSaleModel.CowList) > 0 { for _, cow := range eventSaleModel.CowList { cow.EventSaleUpdate(eventSaleModel.SaleAt, eventSaleModel.SalesType) if err = tx.Model(cow). Select("admission_status", "departure_at", "neck_ring_number", "HealthStatus"). Where("id = ?", cow.Id). Updates(cow).Error; err != nil { return xerr.WithStack(err) } } } if len(eventSaleModel.NeckRingList) > 0 { for _, neckRing := range eventSaleModel.NeckRingList { cowInfo := &model.Cow{Id: neckRing.CowId, EarNumber: neckRing.EarNumber} neckRing.EventUnBindUpdate() if err = tx.Model(new(model.NeckRing)). Select("is_bind", "cow_id", "ear_number", "wear_at", "error_reason", "operation_id", "operation_name"). Where("id = ?", neckRing). Updates(neckRing).Error; err != nil { return xerr.WithStack(err) } newNeckRingBindLog := model.NewNeckRingBindLog(userModel.AppPasture.Id, neckRing.NeckRingNumber, cowInfo, userModel.SystemUser, "死亡解绑") if err = tx.Model(new(model.NeckRingBindLog)).Create(newNeckRingBindLog).Error; err != nil { return xerr.WithStack(err) } } } // 记录日志 if len(eventSaleModel.EventCowLog) > 0 { for _, cowLog := range eventSaleModel.EventCowLog { if err = tx.Table(cowLog.TableName()).Create(cowLog).Error; err != nil { return xerr.WithStack(err) } } } return nil }); err != nil { return xerr.WithStack(err) } return nil } func (s *StoreEntry) CowSaleList(ctx context.Context, req *pasturePb.EventCowSaleRequest, pagination *pasturePb.PaginationModel) (*pasturePb.EventCowSaleResponse, error) { userModel, err := s.GetUserModel(ctx) if err != nil { return nil, xerr.WithStack(err) } eventSale := make([]*model.EventSale, 0) var count int64 pref := s.DB.Model(new(model.EventSale)). Where("pasture_id = ?", userModel.AppPasture.Id) if req.StartDayAt > 0 && req.EndDayAt > 0 && req.EndDayAt >= req.StartDayAt { pref.Where("sale_at BETWEEN ? AND ?", req.StartDayAt, req.EndDayAt) } if req.DealerId > 0 { pref.Where("dealer_id = ?", req.DealerId) } if err = pref.Order("id desc"). Count(&count).Limit(int(pagination.PageSize)). Offset(int(pagination.PageOffset)). Find(&eventSale).Error; err != nil { return nil, xerr.WithStack(err) } saleIds := make([]int64, 0) for _, v := range eventSale { saleIds = append(saleIds, v.Id) } eventSaleCarList := make([]*model.EventSaleCar, 0) if err = s.DB.Model(new(model.EventSaleCar)). Where("pasture_id = ?", userModel.AppPasture.Id). Where("sale_id IN (?)", saleIds). Find(&eventSaleCarList).Error; err != nil { return nil, xerr.WithStack(err) } eventSaleCarMap := make(map[int64][]*model.EventSaleCar) for _, car := range eventSaleCarList { if eventSaleCarMap[car.SaleId] == nil { eventSaleCarMap[car.SaleId] = make([]*model.EventSaleCar, 0) } eventSaleCarMap[car.SaleId] = append(eventSaleCarMap[car.SaleId], car) } eventSaleCowList := make([]*model.EventSaleCow, 0) if err = s.DB.Model(new(model.EventSaleCow)). Where("pasture_id = ?", userModel.AppPasture.Id). Where("sale_id IN (?)", saleIds). Find(&eventSaleCowList).Error; err != nil { return nil, xerr.WithStack(err) } eventSaleCowMap := make(map[int64][]*model.EventSaleCow) for _, cow := range eventSaleCowList { if eventSaleCowMap[cow.SaleId] == nil { eventSaleCowMap[cow.SaleId] = make([]*model.EventSaleCow, 0) } eventSaleCowMap[cow.SaleId] = append(eventSaleCowMap[cow.SaleId], cow) } return &pasturePb.EventCowSaleResponse{ Code: http.StatusOK, Msg: "ok", Data: &pasturePb.EventCowSaleData{ List: model.EventSaleSlice(eventSale).ToPB(eventSaleCarMap, eventSaleCowMap), Total: int32(count), PageSize: pagination.PageSize, Page: pagination.Page, }, }, nil } func (s *StoreEntry) ImmunizationList(ctx context.Context, req *pasturePb.SearchEventImmunizationRequest, pagination *pasturePb.PaginationModel) (*pasturePb.SearchEventImmunizationResponse, error) { userModel, err := s.GetUserModel(ctx) if err != nil { return nil, xerr.WithStack(err) } eventImmunizationList := make([]*model.EventImmunizationPlan, 0) var count int64 pref := s.DB.Model(new(model.EventImmunizationPlan)). Where("pasture_id = ?", userModel.AppPasture.Id). Where("status = ?", pasturePb.IsShow_Ok) if req.StartDayAt > 0 && req.EndDayAt > 0 && req.StartDayAt <= req.EndDayAt { pref.Where("reality_day BETWEEN ? AND ?", req.StartDayAt, req.EndDayAt) } if len(req.CowIds) > 0 { pref.Where("cow_id IN (?)", req.CowIds) } if err = pref.Order("plan_id ASC,reality_day DESC"). Count(&count).Limit(int(pagination.PageSize)). Offset(int(pagination.PageOffset)). Find(&eventImmunizationList).Error; err != nil { return nil, xerr.WithStack(err) } return &pasturePb.SearchEventImmunizationResponse{ Code: http.StatusOK, Msg: "ok", Data: &pasturePb.EventImmunizationData{ List: model.EventImmunizationPlanSlice(eventImmunizationList).ToPB2(), Total: int32(count), PageSize: pagination.PageSize, Page: pagination.Page, }, }, nil } // ImmunizationBatch 只能提交同一个免疫计划类型的数据 func (s *StoreEntry) ImmunizationBatch(ctx context.Context, req *pasturePb.ImmunizationItem) error { userModel, err := s.GetUserModel(ctx) if err != nil { return xerr.WithStack(err) } if len(req.EarNumbers) <= 0 { return xerr.Custom("请选择相关牛只数据") } eventImmunizationList := make([]*model.EventImmunizationPlan, 0) if err = s.DB.Model(new(model.EventImmunizationPlan)). Where("pasture_id = ?", userModel.AppPasture.Id). Where("plan_id = ?", req.PlanId). Where("ear_number IN (?)", strings.Join(req.EarNumbers, ",")). Find(&eventImmunizationList).Error; err != nil { return xerr.WithStack(err) } if len(eventImmunizationList) != len(req.EarNumbers) { return xerr.Custom("数据异常") } drugsInfo := &model.Drugs{} if err = s.DB.Model(new(model.Drugs)). Where("pasture_id = ?", userModel.AppPasture.Id). Where("id = ?", req.DrugsId). First(drugsInfo).Error; err != nil { return xerr.WithStack(err) } operationUser, err := s.GetSystemUserById(ctx, int64(req.OperationId)) if err != nil { return xerr.WithStack(err) } if err = s.DB.Transaction(func(tx *gorm.DB) error { for _, eventImmunization := range eventImmunizationList { cowInfo, err := s.GetCowInfoByCowId(ctx, userModel.AppPasture.Id, eventImmunization.CowId) if err != nil { return xerr.WithStack(err) } // 更新数据 eventImmunization.EventUpdate(int64(req.ImmunizationAt), cowInfo, drugsInfo, req.Usage, operationUser, userModel.SystemUser, req.Remarks) if err = tx.Model(new(model.EventImmunizationPlan)). Select("ear_number", "lact", "day_age", "status", "operation_id", "operation_name", "message_id", "message_name", "drugs_id", "drugs_name", "usage", "unit", "unit_name", "reality_day", "remarks"). Where("id = ?", eventImmunization.Id). Updates(eventImmunization).Error; err != nil { return xerr.WithStack(err) } // 记录日志 cowLog := s.SubmitEventLog(ctx, userModel.AppPasture.Id, cowInfo, pasturePb.EventType_Immunication, eventImmunization) if err = tx.Table(cowLog.TableName()).Create(cowLog).Error; err != nil { return xerr.WithStack(err) } } return nil }); err != nil { return xerr.WithStack(err) } return nil }